扩展方法有什么好处呢?

发布于 2024-08-11 05:52:13 字数 1080 浏览 6 评论 0原文

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

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

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

对我来说,任何使用如下扩展方法的代码

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

都会产生误导,因为它暗示 SomeExtensionMethodThing 的实例成员,这会误导开发人员相信(至少作为一种直觉......你可能会否认这一点,但我确实观察到了这一点)(1)SomeExtensionMethod可能是有效实现的,并且(2)因为SomeExtensionMethod实际上看起来它是 Thing 类的一部分,如果 Thing 在将来的某个时刻被修改,它肯定会保持有效(只要Thing 的作者知道他/她在做什么)。

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

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

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

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

我缺少什么?为什么存在扩展方法?

Possible Duplicate:
What Advantages of Extension Methods have you found?

All right, first of all, I realize this sounds controversial, but I don't mean to be confrontational. I am asking a serious question out of genuine curiosity (or maybe puzzlement is a better word).

Why were extension methods ever introduced to .NET? What benefit do they provide, aside from making things look nice (and by "nice" I mean "deceptively like instance methods")?

To me, any code that uses an extension method like this:

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

is misleading, because it implies that SomeExtensionMethod is an instance member of Thing, which misleads developers into believing (at least as a gut feeling... you may deny it but I've definitely observed this) that (1) SomeExtensionMethod is probably implemented efficiently, and (2) since SomeExtensionMethod actually looks like it's part of the Thing class, surely it will remain valid if Thing is revised at some point in the future (as long as the author of Thing knows what he/she's doing).

But the fact is that extension methods don't have access to protected members or any of the internal workings of the class they're extending, so they're just as prone to breakage as any other static methods.

We all know that the above could easily be:

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

To me, this seems a lot more, for lack of a better word, honest.

What am I missing? Why do extension methods exist?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

゛时过境迁 2024-08-18 05:52:13

需要扩展方法来使 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);

任何事物一样,它们可能会被滥用,但扩展方法在正确使用时非常有用。

Extension methods were needed to make Linq work in the clean way that it does, with method chaining. If you have to use the "long" form, it causes the function calls and the parameters to become separated from each other, making the code very hard to read. Compare:

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

versus

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

Like anything, they can be abused, but extension methods are really useful when used properly.

给我一枪 2024-08-18 05:52:13

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

I think that the main upside is discoverability. Type initial and a dot, and there you have all the stuff that you can do with it. It's a lot harder to find static methods tucked away in some class somewhere else.

再浓的妆也掩不了殇 2024-08-18 05:52:13

首先,在 Thing Operad = SomeNonExtensionMethod(initial); 情况下,SomeNonExtensionMethod 与 Thing Operad = Initial.SomeExtensionMethod(); 中的假设完全相同。案件。事情可能会改变,SomeExtensionMethod 可能会中断。这就是我们程序员的生活。

其次,当我看到 Thing Operated = initial.SomeExtensionMethod(); 时,它并没有告诉我 SomeExtensionMethod() 的具体实现位置。 Thing 可以从 TheThing 继承它,TheThing 又从 TheOriginalThing 继承它。所以“误导性”的说法是没有任何结果的。我敢打赌 IDE 会负责引导您找到正确的来源,不是吗?

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

First of all, in the Thing manipulated = SomeNonExtensionMethod(initial); case, SomeNonExtensionMethod is based on exactly the same assumptions like in the Thing manipulated = initial.SomeExtensionMethod(); case. Thing can change, SomeExtensionMethod can break. That's life for us programmers.

Second, when I see Thing manipulated = initial.SomeExtensionMethod();, it doesn't tell me exactly where SomeExtensionMethod() is implemented. Thing could inherit it from TheThing, which inherits it from TheOriginalThing. So the "misleading" argument leads to nowhere. I bet the IDE takes care of leading you to the right source, doesn't it?

What's so great? It makes code more consistent. If it works on a string, it looks like if it was a member of string. It's ugly to have several MyThing.doThis() methods and several static ThingUtil.doSomethingElse(Mything thing) methods in another class.

橪书 2024-08-18 05:52:13

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

SO you can extend someone else's class. not yours... that's the advantage.
(and you can say.. oh I wish they implement this / that.... you just do it yourself..)

清欢 2024-08-18 05:52:13

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

Linq 经常使用这一点。

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

they are great for automatically mixing in functionality based on Interfaces that a class inherits without that class having to explicitly re implement it.

Linq makes use of this a lot.

Great way to decorate classes with extra functionality. Most effective when applied to an Interface rather than a specific class. Still a good way to extend Framework classes though.

暮光沉寂 2024-08-18 05:52:13

它只是方便的语法糖,因此您可以使用相同的语法调用方法,无论它实际上是否是类的一部分。如果甲方发布了一个库,而乙方发布了使用该库的内容,则使用 class.method(args) 调用所有内容比必须记住使用 method(class, args) 与 class.method 调用的内容更容易(参数)。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文