tags:

views:

504

answers:

7

In which situations I should use LINQ to Objects?

Obviously I can do everything without LINQ. So in which operations LINQ actually helps me to code shorter and/or more readable?

This question triggered by this

A: 

LINQ is pretty useful in a few scenarios:

  • You want to use typed "business entities", instead of data tables, to more naturally access your data (and aren't already using something like NHibernate or LLBLGenPro)
  • You want to query non-relational data using a SQL like syntax (this is real handy when querying lists and such)
  • You don't like lots of inline SQL or stored procedures
Jess
That's just LINQ-to-SQL.
MichaelGG
The second bullet point isn't - that would be for querying lists and such with LINQ
Jess
A: 

LINQ comes in to play when you start doing complex filtering on complex data types. For example, if you're given a list of People objects and you need to gather a list of all the doctors within that list. With LINQ, you can compress the following code into a single LINQ statement:

(pseudo-code)

doctors = []
for person in people:
    if person is doctor:
        doctors.append(person)

(sorry, my C# is rusty, type checking syntax is probably incorrect, but you get the idea)

doctors = from person in people where person.type() == doctor select person;
Soviut
In that situation I wouldn't use a query expression - I'd just do people.Where(person => person is Doctor)
Jon Skeet
doctors = people.OfType<Doctor>()
David B
+12  A: 

I find LINQ to Objects useful all over the place. The problem it solves is pretty general:

  • You have a collection of some data items
  • You want another collection, formed from the original collection, but after some sort of transformation or filtering. This might be sorting, projection, applying a predicate, grouping, etc.

That's a situation I come across pretty often. There are an awful lot of areas of programming which basically involve transforming one collection (or stream of data) into another. In those cases the code using LINQ is almost always shorter and more readable. I'd like to point out that LINQ shouldn't be regarded as being synonymous with query expressions - if only a single operator is required, the normal "dot notation" (using extension methods) can often be shorter and more readable.

One of the reasons I particularly like LINQ to Objects is that it is so general - whereas LINQ to SQL is likely to only get involved in your data layer (or pretty much become the data layer), LINQ to Objects is applicable in every layer, and in all kinds of applications.

Just as an example, here's a line in my MiniBench benchmarking framework, converting a TestSuite (which is basically a named collection of tests) into a ResultSuite (a named collection of results):

return new ResultSuite(name, 
    tests.Select(test => test.Run(input, expectedOutput)));

Then again if a ResultSuite needs to be scaled against some particular "standard" result:

return new ResultSuite(name, 
    results.Select(x => x.ScaleToStandard(standard, mode)));

It wouldn't be hard to write this code without LINQ, but LINQ just makes it clearer and lets you concentrate on the real "logic" instead of the details of iterating through loops and adding results to lists etc.

Even when LINQ itself isn't applicable, some of the features which were largely included for the sake of LINQ (e.g. implicitly typed local variables, lambda expressions, extension methods) can be very useful.

Jon Skeet
+4  A: 

The answer practically everywhere comes to mind. A better question would be when not to use it.

Dmitri Nesteruk
OK, doing an HTTP Request, Multhithreading, so what, are we supposed write everything in LINQ?
dr. evil
Multithreading: See PLINQ.
Jon Skeet
Doing an HTTP request is a great example. If you include lambda syntax as part of LINQ (and it'd be wierd not to), then defining your callbacks as closures makes it *much* easier.
MichaelGG
However concise your answer may be, a little more feedback would have been better. In the future try to base your opinion with a little more background so that we may be better influenced by it. Besides that, I did kinda smile at your answer, cuz at face value it's true!
John Baughman
When is PLINQ available? VS 2010?
ccook
Have you seen the ray tracer in LINQ? A bit extreme, but proves the point: LINQ can be abused for practically anything.
Dmitri Nesteruk
I know PLINQ exist as well as LINQ to SQL exist however that doesn't mean they are better than other solutions. My question was when using LINQ makes code better, not how to do everything is LINQ.
dr. evil
A: 

Edit: After I answered I see a change to say "LINQ to Objects". Oh well.

If by LINQ we refer to all the new types in System.Linq, as well as new compiler features, then it'll have quite a bit of benefit -- it is effectively adding functional programming to these languages. ( Here's the progression I've seen a few times (although this is mainly C# -- VB is limited in the current version).

The obvious start is that anything related to list processing gets vastly easier. A lot of loops can just go away. What benefit do you get? You'll start programming more declaratively, which will lead to fewer bugs. Things start to "just work" when switching to this style. (The LINQ query syntax I don't find too useful, unless the queries are very complicated with lots of intermediate values. In these cases, the syntax will sort out all the issues you'd otherwise have to pass tuples around for.)

Next, language support (in C#, and in the next version of VB) for anonymous methods allows you to write a lot more constructs in a much shorter way. For instance, handling an async callback can be defined inside the method that initiates it. Using a closure here will result in you not having to bundle up state into an opaque object parameter and casting it out later on.

Being able to use higher order functions gets you thinking much more generically. So you'll start to see where you could simply pass in a lambda and solve things neater and cleaner. At this point, you'll realise that things only really work if you use generics. Sure, this is a 2.0 feature, but the usage is much more prevalent when you're passing functions around.

And around there, you get into the point of diminishing returns. The cost of declaring and using funcs and declaring all the generic type parameters (in C# and VB) is quite high. The compiler won't work it out for you, so you have to do it all manually. This adds a huge amount of overhead and friction, which limits how far you can go.

So, is this all "LINQ"? Depends on marketing, perhaps. The LINQ push made this style of programming much easier in C#, and all of LINQ is based on FP ideas.

MichaelGG
A: 

Everywhere you see suitable in terms of simplicity and performance. LINQ is not magic, it doesn't have its own shortcuts to make things faster. If the classes you're working on do not implement anything other than IEnumerable, you need to be aware of side effects such as Count() literally counting each and every item in the collection, rather than returning this._count;

If you know what's behind the scenes you can make a better judgement on when to use. One good example would be this recent question asking LINQ way of joining strings where there is a faster non-LINQ way.

ssg
+3  A: 

LINQ is great for the "slippery slope". Think of what's involved in many common operations:

  • Where. Just write a foreach loop and an "if"
  • Select. Create an empty list of the target type, loop through the originals, convert each one and add it to the results.
  • OrderBy. Just add it to a list and call .Sort(). Or implement a bubble sort ;)
  • ThenBy (from order by PropertyA, then by PropertyB). Quite a bit harder. A custom comparer and Sort should do the trick.
  • GroupBy - create a Dictionary<key, List<value>> and loop through all items. If no key exists create it, then add items to the appropriate list.

In each of those cases, the procedural way takes more code than the LINQ way. In the case of "if" it's a couple of lines more; in the case of GroupBy or OrderBy/ThenBy it's a lot more.

Now take an all too common scenario of combining them together. You're suddenly looking at a 10-20 line method which could be solved with 3-4 lines in LINQ. And the LINQ version is guaranteed to be easier to read (once you are familiar with LINQ).

So when do you use LINQ? My answer: whenever you see "foreach" :)

Paul Stovell