是否扩展了一个类型以暴露私有成员的扩展方法?

时间:2015-03-30 09:41:41

标签: c# .net linq extension-methods

最近我被指责扩展自定义类以在私有成员上公开LINQ扩展方法,例如:

public virtual T FirstOrDefault(Expression<Func<T, bool>> predicate)
{
    return _someDbSet.FirstOrDefault(predicate);
}

一些团队成员说这很糟糕。给出的解释是这样的:由于内部方法是扩展方法,外部也应该是。

(为什么)这么糟糕?

2 个答案:

答案 0 :(得分:1)

如果添加与现有扩展方法同名的方法,如果它覆盖&#39;则不存在任何问题。该扩展方法的功能,或签名彼此不兼容(或者如果扩展方法不能应用于该特定类)。

如果这些规则不适用,或者您打算同时使用这两个规则,那么最终会调用哪种方法可能会让您感到困惑。这可能会导致错误,所以我不建议使用与扩展方法同名的方法。

答案 1 :(得分:0)

  

给出的解释是这样的:因为内部方法是扩展方法,外部也应该是。

如果那是争论,那那完全是胡说八道。根据它的逻辑结论,我们不能在实例成员中调用任何静态成员(因为扩展方法只是具有一些语法糖的静态方法,使它们看起来像第一个参数上的实例方法)。一致地应用它,你很快就会完全没有静态方法或根本没有任何对象。

但这里有一个问题:

  

public virtual T FirstOrDefault(Expression&gt; predicate)

FirstOrDefault是一种常用的扩展方法。因此,我们知道每当我们调用它时它会做什么。

如果该类充当包裹_someDbSet的集合,则此方法毫无意义;我们可以使用已经存在的FirstOrDefault

如果该类不作为包裹_someDbSet的集合,则此方法可能会令人困惑,因为它不会像我们期望众所周知的FirstOrDefault那样行动。 / p>

如果该课程为IEnumerableIQueryableFirstOrDefaultFirstOrDefault扩展方法不同,则可能会非常混乱,因为相同的成员名称会产生不同的行为,具体取决于引用对象的方式,而且这很少是一件好事。

相反,如果我们有一个FirstOrDefault实例方法与FirstOrDefault做同样的事情,否则会更有效率,那么这是一个实例方法掩盖扩展的情况方法确实是一件好事;就调用代码而言,没有任何行为差异,只是调用代码的“自由”性能提升,因为它的编写方式与完全相同。