Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is using LINQ against a single object considered a bad practice? [closed]

Tags:

c#

linq

I don't mean this question to be too subjective.

I google'd this for some time but got no specific answers to address this issue. The thing is, I think I'm getting somewhat addicted to LINQ. I already used LINQ to query on lists among other things like using Linq to Sql, Xml, and so on. But then something struck me: "What if I used it to query a single object?" So I did. It may seem wrong like trying to kill a fly with a grenade launcher. Though we all agree it would be artistically pleasant to see.


I consider it very readable, I don't think there is any performance issues regarding to this, but let me show you an example.

In a web application, I need to retrieve a setting from my configuration file (web.config). But this should have a default value if the key is not present. Also, the value I need is a decimal, not a string, which is the default return from ConfigurationManager.AppSettings["myKey"]. Also, my number should not be more than 10 and it should not be negative. I know I could write this:

string cfg = ConfigurationManager.AppSettings["myKey"];
decimal bla;
if (!decimal.TryParse(cfg,out bla))
{
    bla = 0; // 0 is the default value
}
else
{
    if (bla<0 || bla>10)
    {
        bla = 0;
    }
}

Which is not complicated, not convoluted, and easy to read. However, this is how I like it done:

// initialize it so the compiler doesn't complain when you select it after
decimal awesome = 0; 
// use Enumerable.Repeat to grab a "singleton" IEnumerable<string>
// which is feed with the value got from app settings
awesome = Enumerable.Repeat(ConfigurationManager.AppSettings["myKey"], 1)
    // Is it parseable? grab it 
    .Where(value => decimal.TryParse(value, out awesome))
    // This is a little trick: select the own variable since it has been assigned by TryParse
    // Also, from now on I'm working with an IEnumerable<decimal>
    .Select(value => awesome)
    // Check the other constraints
    .Where(number => number >= 0 && number <= 10)
    // If the previous "Where"s weren't matched, the IEnumerable is empty, so get the default value
    .DefaultIfEmpty(0)
    // Return the value from the IEnumerable
    .Single();

Without the comments, it looks like this:

decimal awesome = 0; 
awesome = Enumerable.Repeat(ConfigurationManager.AppSettings["myKey"], 1)
    .Where(value => decimal.TryParse(value, out awesome))
    .Select(value => awesome)
    .Where(number => number >= 0 && number <= 10)
    .DefaultIfEmpty(0)
    .Single();

I don't know if I'm the only one here, but I feel the second method is much more "organic" than the first one. It's not easily debuggable, because of LINQ, but it's pretty failproof I guess. At least this one I wrote. Anyway, if you needed to debug, you could just add curly braces and return statements inside the linq methods and be happy about it.

I've been doing this for a while now, and it feels much more natural than doing things "line per line, step by step". Plus, I just specified the default value once. And it's written in a line which says DefaultIfEmpty so it's pretty straightforward.

Another plus, I definitely don't do it if I notice the query will be much larger than the one I wrote up there. Instead, I break into smaller chunks of linq glory so it will be easier to understand and debug.

I find it easier to see a variable assignment and automatically think: this is what you had to do to set this value, rather than look at ifs,elses,switches, and etc, and try to figure out if they're part of the formula or not.

And it prevents developers from writing undesired side effects in wrong places, I think.

But in the end, some could say it looks very hackish, or too arcane.

So I come with the question at hand:

Is using LINQ against a single object considered a bad practice?

like image 337
Conrad Clark Avatar asked Jul 18 '13 01:07

Conrad Clark


People also ask

Is it bad to use LINQ?

The LINQ architecture is good - but some may prefer to read source code that does not use the LINQ SQL-like syntax. So if you're strict on readability, you may want not to use that syntax. Readability is not that big issue.

When should we use LINQ?

LINQ in C# is used to work with data access from sources such as objects, data sets, SQL Server, and XML. LINQ stands for Language Integrated Query. LINQ is a data querying API with SQL like query syntaxes. LINQ provides functions to query cached data from all kinds of data sources.

Does LINQ improve performance?

LINQ syntax is typically less efficient than a foreach loop. It's good to be aware of any performance tradeoff that might occur when you use LINQ to improve the readability of your code. And if you'd like to measure the performance difference, you can use a tool like BenchmarkDotNet to do so.

What is the advantages of using LINQ?

Advantages of LINQIt gives type checking of the object at compile time. It provides IntelliSense for generic collections. It can be used with array or collections. LINQ supports filtering, sorting, ordering, grouping.


1 Answers

I say yes, but it's really up to preference. It definitely has disadvantages, but I will leave that up to you. Your original code can become much simpler though.

string cfg = ConfigurationManager.AppSettings["myKey"];
decimal bla;
if (!decimal.TryParse(cfg,out bla) || bla < 0 || bla > 10)
    bla = 0; // 0 is the default value

This works because of "short circuit" evaluation, meaning that the program will stop checking other conditions once the first true condition is found.

like image 106
Darren Kopp Avatar answered Nov 15 '22 07:11

Darren Kopp