I prefer to use extension methods for the basic LINQ operations: Where()
, Select
, but for complex Select()
, SelectMany()
, and especially OrderBy().ThenBy()
statements I find the query syntax to be much more readable and natural.
Today I found myself with 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 any other reason) to mix query and extension syntax?
This has potential to be very subjective, if it is, I'm sorry if it doesn't meet the requirements for a good subjective question. Let me know if I can improve it!
Is it dangerous (for readability, maintainability, or any other reason) to mix query and extension syntax?
The biggest danger I'd see is the potential addition of "surprise" in your code, especially when viewed by other developers.
From a compilation standpoint, the query syntax is translated directly into the extension method calls, so there isn't necessarily a technical problem here. However, this is potentially going to be adding extra method calls that wouldn't, at a first glance, be expected by many developers. This could lead to a potential maintainability problem.
That being said, if done sparingly and with good reason, I don't feel that there is a real problem with mixing the syntax. This is actually quite common - for example, if you want to write in query syntax, but need to fully evaluate, it's often wrapped in parenthesis with .ToList() added - or if you want to use PLINQ with query syntax, it's often from x in collection.AsParallel()
, which is technically mixing syntax as well...
You could 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 queries aren't mixed
This is kind of a judgment call, but many "best practice"-type questions tend to be, at least at first. My opinion is that you should use one or the other within a single statement. Not really for any "danger" inherent in mixing, but for clarity.
In this particular case, the where clause is very simple, and I would refactor it into query syntax.
There are however cases that cannot be elegantly expressed in query syntax. In cases where it is simply unavoidable to mix syntaxes, the queries would (again IMO) be more readable if you split out the method chain into its own variable, then simply referenced that variable in the query-syntaxed statement. Using yours 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 };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With