4

可能重复:
您发现扩展方法的哪些优点?

好吧,首先,我意识到这听起来有争议,但我并不是要对抗。我出于真正的好奇心提出了一个严肃的问题(或者困惑是一个更好的词)。

为什么将扩展方法引入 .NET?除了让事情看起来不错(我所说的“不错”是指“看似实例方法”)之外,它们还提供什么好处?

对我来说,任何使用这样的扩展方法的代码:

Thing initial = GetThing();
Thing manipulated = initial.SomeExtensionMethod();

具有误导性,因为它暗示 thatSomeExtensionMethod是 的实例成员Thing,这会误导开发人员相信(至少作为一种直觉......你可能会否认它,但我肯定已经观察到这一点)(1)SomeExtensionMethod可能是有效实现的,并且(2) 因为SomeExtensionMethod它实际上看起来像是课程的一部分,所以如果在未来的某个时候进行修改Thing,它肯定会保持有效Thing(只要作者Thing知道他/她在做什么)。

但事实是扩展方法无法访问受保护的成员或它们正在扩展的类的任何内部工作,因此它们与任何其他静态方法一样容易损坏。

我们都知道,上面很容易是:

Thing initial = GetThing();
Thing manipulated = SomeNonExtensionMethod(initial);

我来说,这似乎更多,因为没有更好的词,诚实

我错过了什么?为什么存在扩展方法?

4

6 回答 6

14

需要扩展方法来使 Linq 以干净的方式工作,并使用方法链接。如果必须使用“长”形式,则会导致函数调用和参数彼此分离,从而使代码难以阅读。比较:

IEnumerable<int> r = list.Where(x => x > 10).Take(5)

相对

// What does the 5 do here?
IEnumerable<int> r = Enumerable.Take(Enumerable.Where(list, x => x > 10), 5);

像任何东西一样,它们可能会被滥用,但是如果使用得当,扩展方法确实很有用。

于 2009-11-18T22:30:21.543 回答
6

我认为主要的好处是可发现性。输入initial和一个点,你就可以用它做所有的事情了。在其他地方的某个类中找到隐藏的静态方法要困难得多。

于 2009-11-18T22:30:46.587 回答
3

首先,在本Thing manipulated = SomeNonExtensionMethod(initial);例中, SomeNonExtensionMethod 基于与本例完全相同的假设Thing manipulated = initial.SomeExtensionMethod();。事情可以改变, SomeExtensionMethod 可以打破。这就是我们程序员的生活。

其次,当我看到时Thing manipulated = initial.SomeExtensionMethod();,它并没有准确地告诉我 SomeExtensionMethod() 是在哪里实现的。Thing 可以从 TheThing 继承它,而 TheThing 从 TheOriginalThing 继承它。因此,“误导”论点毫无结果。我敢打赌 IDE 会负责引导您找到正确的来源,不是吗?

有什么了不起?它使代码更加一致。如果它适用于字符串,则看起来它是否是字符串的成员。在另一个类中有几个MyThing.doThis()方法和几个方法是很难看的。static ThingUtil.doSomethingElse(Mything thing)

于 2009-11-18T22:34:09.270 回答
0

所以你可以扩展别人的课程。不是你的……这就是优势。(你可以说......哦,我希望他们实现这个/那个......你自己做......)

于 2009-11-18T22:30:12.657 回答
0

它们非常适合基于类继承的接口自动混合功能,而无需该类显式地重新实现它。

Linq 充分利用了这一点。

用额外的功能装饰类的好方法。应用于接口而不是特定类时最有效。仍然是扩展框架类的好方法。

于 2009-11-18T22:35:22.703 回答
0

It's just convenient syntactic sugar so that you can call a method with the same syntax regardless of whether it's actually part of the class. If party A releases a lib, and party B releases stuff that uses that lib, it's easier to just call everything with class.method(args) than to have to remember what gets called with method(class, args) vs. class.method(args).

于 2009-11-18T22:38:30.013 回答