2

我突然想到我用简单的方式写出 linq 语句,但其他人可能会定义为冗长的方式;

一个简单的例子:

return _entries
    .Where(x => x.Context.Equals(context))
    .Where(x => x.Type == typeof (T))
    .Select(x=>x.Value)
    .Cast<T>()
    .Single();

可以简化为:

return _entries
    .Where(x => x.Context.Equals(context) && x.Type == typeof (T))
    .Select(x=>(T)x.Value)
    .Single();

[问题] 从长远来看,哪种编码方式更好?即长(和简单)linq 链或具有更复杂选择器/等的短 linq 链?

假设这些 Linq 语句将被编译器优化是正确的吗?

4

4 回答 4

9

从长远来看,哪种编码方式更好?

我更喜欢简短而简单的。它更具可读性。LINQ 的全部意义在于让代码读起来更像业务领域的逻辑。

假设这些 Linq 语句将被编译器优化是正确的吗?

不; 优化是由运行时完成的,而不是由编译器完成的。LINQ-to-objects 遵循您描述的模式的“Where”和“Select”子句在运行时优化为单个“where-select”对象,以避免创建太多迭代器。(尽管正如 Jon Skeet 发现的那样,这有时会产生性能实际上下降的情况;就像几乎所有“优化”一样,这并不是 100% 的胜利。不幸的是,我现在找不到 Jon 的文章。 )

于 2013-03-01T17:50:49.067 回答
5

不,假设这些 LINQ 语句已由编译器优化是不正确的。更冗长的语法会产生更多Enumerator的对象,因此两者并不等价。从性能的角度来看,较短的语法将(稍微)更好。

但是,如果您从可读性和编码的角度在两种语法之间进行选择,我会选择第一种,因为它显示了更好的步骤。我总是更喜欢可读性而不是性能,除非你可以证明存在性能瓶颈。

但是,有一个您可能会发现有用的OfType<T>()LINQ 运算符。你的第一个例子,重写:

return _entries
    .Where(x => x.Context.Equals(context))
    .OfType<T>()
    .Select(x => (T)x.Value)
    .Single();
于 2013-03-01T17:04:00.760 回答
4

从长远来看,更好的编码实践是更具可读性的实践。如果您担心性能,请测试这两种方法。如果它不值得测试,那么它就不值得优化。

于 2013-03-01T17:14:23.723 回答
1

我喜欢 Linq 表达式,因为它提供了一种以声明方式表达代码意图的方法。它专注于想要实现的目标,而不是如何实现它。所以强调代码的可读性。

但是用 Linq 运算符替换一些 for/foreach 块也可能使代码实现起来很麻烦。所以我建议把你的表达式写成冗长的,这样你就可以向你的共同程序员口头描述逻辑,例如,下面的表达式可以描述为“返回一个类型为 T 的单个值,其中条目上下文等于上下文和类型等于 T”。如果需要,编写自定义扩展方法,例如As<T>()将值转换为 T 类型。

return _entries
    .Where(x => x.Context.Equals(context) && x.Type == typeof (T))
    .Single (x=> x.Value)
    .As<T>();
于 2013-03-02T07:13:13.850 回答