linq - 你会把你的 LINQ 查询抽象成扩展方法吗

标签 linq extension-methods abstraction maintainability cyclomatic-complexity

在我当前的项目中,我们为代码指标“可维护性指数”和“循环复杂度”设定了一些目标。可维护性指数应为 60 或更高,循环复杂度应为 25 或更低。我们知道 60 及更高的可维护性指数是一个相当高的指数。

我们还使用了很多 linq 来过滤/分组/选择实体。我发现这些 linq 查询在可维护性指数上的得分并不高。
将这个查询抽象为扩展方法给了我一个更高的可维护性指数,这很好。但在大多数情况下,扩展方法不再是通用的,因为我将它们与我的类型而不是通用类型一起使用。

例如下面的 linq-query vs 扩展方法:

Linq查询

List.Where(m => m.BeginTime >= selectionFrom && m.EndTime <= selectionTo)

分机方式:
public static IEnumerable<MyType> FilterBy(this IEnumerable<MyType> source, DateTime selectionFrom, DateTime selectionTo)
{
    return (IEnumerable<MyType>)source.Where(m => m.BeginTime >= selectionFrom && m.EndTime <= selectionTo);
}

List.FilterBy(selectionFrom, selectionTo);

扩展方法使我的可维护性指数提高了 6 分,并提供了流畅的语法。
另一方面,我必须添加一个静态类,它不是通用的。

关于哪种方法会得到您的青睐的任何想法?或者也许对如何重构 linq 查询以提高可维护性指数有不同的想法?

最佳答案

您不应该为了度量而添加类。任何指标都旨在使您的代码 更好 但盲目遵守规则,即使是最好的规则,实际上可能会损害您的代码 .

我认为坚持某些可维护性和复杂性指标不是一个好主意。我相信它们对于评估旧代码很有用 ,即当您继承一个项目并需要估计其复杂性时。然而,因为你没有得到足够的分数而提取一个方法是荒谬的。

仅当此类重构为代码增加值(value)时才重构。 这种值(value)是一个复杂的人类指标,无法用数字表达,而估计它正是编程体验的意义所在——在优化、可读性、干净的 API、酷代码、简单代码、快速交付、泛化与规范等之间找到平衡。

这是您应该遵循的唯一指标,但并不总是每个人都同意的指标......

对于您的示例,如果反复使用相同的 LINQ 查询,则创建 EnumerableExtensions 非常有意义。在 Extensions文件夹并将其解压缩到那里。但是,如果它使用了一次或两次,或者可能会发生变化,详细查询要好得多。

我也不明白为什么你说它们不是带有负面含义的通用。你不需要无处不在的泛型!实际上,在编写扩展方法时,您应该考虑可以选择的最具体的类型,以免污染其他类的方法集。如果您希望您的助手只与 IEnumerable<MyType> 一起工作,完全没有为 this IEnumerable<MyType> 声明一个扩展方法而感到羞耻。 .顺便说一句,您的示例中有多余的类型转换 .摆脱它。

并且不要忘记,工具是愚蠢的。我们人类也是。

关于linq - 你会把你的 LINQ 查询抽象成扩展方法吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6276237/

相关文章:

c# - 等效的 lambda 值是多少?

c# - 选择最小和最大 LINQ

linq - linq 结果中的 foreach 不起作用

asp.net - VB.Net 使用 System.Reflection 和 System.Type 初始化类以创建基于 session 的单例扩展方法

c# - 在 linq 查询中使用 string.IsnullorEmpty 的问题

c# - 您最喜欢的 C# 扩展方法是什么? (codeplex.com/extensionoverflow)

javascript - (扩展)更新选项卡时保存更改的值

java - 将泛型参数限制为 Java 中的不同类型

c - 为其他类型重新利用相同的 c ADT

java - 包可见性