繁体   English   中英

Linq混合扩展和查询语法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM