Linq mix extension and query syntax

I prefer to use extension methods for the basic LINQ operations: Where() , Select , but for complex Select() , SelectMany() and especially SelectMany() operators OrderBy().ThenBy() I find the query syntax more readable and natural.

Today I found the following query:

 from c in _myObject.ObjectsParent.ParentsEnumerable .Where(c => c == anotherObject || c.Parent == anotherObject) from q in c.MyObjectsEnumerable orderby c.SortKey, q.Description select new { Item = q, Text = c.Description + " -> " + q.Description }; 

Is it dangerous (for readability, maintainability, or for any other reason) to mix query syntax and extension?

It has the potential to be very subjective, if so, I am sorry if it does not meet the requirements of a good subjective question. Let me know if I can improve it!

+8
c # linq
source share
6 answers

Is it dangerous (for readability, maintainability, or for any other reason) to mix query syntax and extension?

The biggest danger I would see is the potential addition of “surprise” to your code, especially when viewed by other developers.

From a compilation point of view, the query syntax translates directly into calls to the extension method, so there is no technical problem. However, this will potentially add additional method calls that, at first glance, would not be expected by many developers. This can lead to a potential maintainability problem.

Speaking, if this is done with restraint and with good reason, I don’t feel that there is a real problem with mixing syntax. This is actually quite common - for example, if you want to write in the query syntax, but you need to fully evaluate it, it often ends in brackets with the addition of .ToList () or if you want to use PLINQ with the query syntax, then often from x in collection.AsParallel() , which also technically mixes the syntax ...

+6
source share

You can do something like this to make things a little easier.

 var firstQuery = _myObject.ObjectsParent.ParentsEnumerable .Where(c => c == anotherObject || c.Parent == anotherObject); var secondQuery = from q in firstQuery.MyObjectsEnumerable orderby firstQuery.SortKey, q.Description select new { Item = q, Text = firstQuery.Description + " -> " + q.Description }; 

Now your requests don't mix

+3
source share

This is a kind of call to judgment, but many questions of “best practice” usually have, at least in the beginning. My opinion is that you should use one or the other as part of a single application. Not for any “danger” inherent in mixing, but for clarity.

In this particular case, the where clause is very simple, and I would reorganize it into the query syntax.

However, there are cases that cannot be elegantly expressed in the query syntax. In cases where it is simply impossible to mix syntaxes, queries (again IMO) can be more readable if you split the method chain into your own variable and then just refer to that variable in the syntax query. Using your model as a model:

 //The method chain can be pulled out as its own variable... var filteredParents = _myObject.ObjectsParent.ParentsEnumerable .Where(c => c == anotherObject || c.Parent == anotherObject); //...which you can then substitute in a now purely query-syntax statement from c in filteredParents from q in c.MyObjectsEnumerable orderby c.SortKey, q.Description select new { Item = q, Text = c.Description + " -> " + q.Description }; 
+3
source share

I don’t think it’s dangerous to mix, he thinks that it depends on what is more readable, the query syntax is very readable, but not so flexible, so mixing some chains seems like a small price. I guess the answer is whether you think the next complete chain is more readable than what you wrote, I personally find it easier to read yours.

  _myObject.ObjectsParent .ParentsEnumerable .Where(c => c == anotherObject || c.Parent == anotherObject) .SelectMany(c => c.MyObjectsEnumerable, (c, q) => new {c, q}) .OrderBy(t => tcSortKey) .ThenBy(t => tqDescription) .Select(t => new {Item = tq, Text = tcDescription + " -> " + tqDescription}); 
+2
source share

I use extension methods, my colleague uses query syntax. There is no difference.

I would say that you have to break a large request into smaller ones for debugging and reading, since there is usually no time consuming.

+1
source share

Having done this myself (although not for .Where, but for .Cast), I would say that it very much depends on what extension methods you call.

eg. I felt quite qualified to use. Cast because it was not available in syntactic sugar (AFAIK), but probably would have avoided it. If it has a view in the query syntax.

Having said that, I would probably use. Choose to also mutate the data in the query ... But I'm a bit sadistic.

+1
source share

All Articles