我更喜欢使用扩展方法进行基本的LINQ操作:Where()
,Select
,但对于复杂的Select()
,SelectMany()
,尤其是OrderBy().ThenBy()
语句我发现查询语法更具可读性和自然性。
今天我发现自己有以下问题:
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 };
混合查询和扩展语法是否危险(出于可读性,可维护性或任何其他原因)?
这有可能是非常主观的,如果是,如果它不符合一个好的主观问题的要求,我很抱歉。如果我能改进它,请告诉我!
答案 0 :(得分:6)
混合查询和扩展语法是否危险(出于可读性,可维护性或任何其他原因)?
我看到的最大危险是代码中可能会增加“惊喜”,尤其是在其他开发人员查看时。
从编译的角度来看,查询语法直接转换为扩展方法调用,因此这里不一定存在技术问题。但是,这可能会增加额外的方法调用,乍一看,许多开发人员都不会这样做。 可能导致潜在的可维护性问题。
话虽如此,如果谨慎而有充分理由,我并不认为混合语法存在真正的问题。这实际上很常见 - 例如,如果你想用查询语法编写,但需要完全评估,它通常用括号括起来添加.ToList() - 或者如果你想使用带有查询语法的PLINQ,它通常是{ {1}},这在技术上也是混合语法......
答案 1 :(得分:3)
你可以做这样的事情,让事情变得更容易。
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 };
现在您的查询没有混合
答案 2 :(得分:3)
这是一种判断,但许多“最佳实践”类型的问题往往是,至少在开始时。我的意见是你应该在一个声明中使用其中一个。不是因为混合中固有的任何“危险”,而是为了清晰起见。
在这种特殊情况下,where子句非常简单,我会将其重构为查询语法。
但是有些情况无法在查询语法中优雅地表达。如果只是不可避免地混合语法,那么如果将方法链拆分为自己的变量,那么查询将(再次IMO)更具可读性,然后在查询语法语句中简单地引用该变量。用你的模特作为模特:
//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 :(得分:2)
我不认为混合是危险的,它认为它取决于什么是更可读,查询语法是非常可读的,但不是灵活的,所以混合一些链接似乎是一个很小的代价。我想答案是你是否认为以下完全链接比你写的更容易阅读,我个人认为你的更容易阅读。
_myObject.ObjectsParent
.ParentsEnumerable
.Where(c => c == anotherObject || c.Parent == anotherObject)
.SelectMany(c => c.MyObjectsEnumerable, (c, q) => new {c, q})
.OrderBy(t => t.c.SortKey)
.ThenBy(t => t.q.Description)
.Select(t => new {Item = t.q, Text = t.c.Description + " -> " + t.q.Description});
答案 4 :(得分:1)
我使用扩展方法,我的同事使用查询语法。没有区别。
但是我会说你应该将大型查询分解为较小的查询以进行调试和阅读,因为通常没有时间成本。
答案 5 :(得分:1)
我自己完成了这项工作(虽然不是。但是,但是对于.Cast)我会说这很大程度上取决于你所使用的扩展方法。
e.g。我觉得完全有资格使用.Cast,因为它在语法糖(AFAIK)中不可用,但可能会避免。因为它在查询语法中有表示。
话虽如此,我可能会使用.Select来改变查询中的数据......但我有点像个虐待狂。