[英]Linq mix extension and query syntax
我更喜欢使用扩展方法进行基本的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 };
混合查询和扩展语法是危险的(出于可读性,可维护性或任何其他原因)?
这有可能是非常主观的,如果是,我很抱歉,如果它不符合一个好的主观问题的要求。 如果我可以改进它,请告诉我!
混合查询和扩展语法是危险的(出于可读性,可维护性或任何其他原因)?
我看到的最大危险是你的代码中可能会增加“惊喜”,特别是在其他开发人员查看时。
从编译的角度来看,查询语法直接转换为扩展方法调用,因此这里不一定存在技术问题。 但是,这可能会增加额外的方法调用,乍一看,许多开发人员都不会这样做。 这可能会导致潜在的可维护性问题。
话虽这么说,如果谨慎而有充分理由,我不觉得混合语法存在真正的问题。 这实际上很常见 - 例如,如果你想用查询语法编写,但需要完全评估,它通常用括号添加.ToList()添加 - 或者如果你想将PLINQ与查询语法一起使用,它通常from x in collection.AsParallel()
,这在技术上也是混合语法......
你可以做这样的事情让事情变得更容易一些。
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 };
现在你的查询没有混合
这是一种判断,但许多“最佳实践”类型的问题往往是,至少在开始时。 我的意见是你应该在一个声明中使用其中一个。 不是因为混合中固有的“危险”,而是为了清晰起见。
在这种特殊情况下,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 };
我不认为混合是危险的,它认为它取决于什么是更可读,查询语法是非常可读的,但不是灵活的,所以混合一些链接似乎是一个很小的代价。 我想答案是你是否认为以下完全链接比你写的更具可读性,我个人认为你的更容易阅读。
_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});
我使用扩展方法,我的同事使用查询语法。 没有区别。
然而,我会说你应该将大型查询分解为较小的查询以进行调试和可读性,因为通常没有时间成本。
自己完成了这个(虽然不是。但是对于.Cast)我会说这很大程度上取决于你所调用的扩展方法。
例如,我觉得完全有权使用.Cast,因为它在语法糖(AFAIK)中不可用,但可能会避免。因为它在查询语法中有一个表示。
话虽如此,我可能会使用.Select来改变查询中的数据......但我有点像一个虐待狂。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.