扩展方法与继承

djc*_*uch 42 .net c# inheritance extension-methods class

是否有经验法则有助于确定在哪种情况下使用哪个?我最喜欢哪一个?

谢谢!

wom*_*omp 33

扩展方法很有用,但它们通过IDE比常规方法更难发现,因为它们没有附加到原始类,并且没有关于它们的代码可能驻留在何处的线索.关于在何处放置它们以及如何命名它们,有一些最佳实践建议,但这些仅是指导原则,并且不保证有人会遵循它们.

通常,如果您只是为一个众所周知的,使用良好的类或接口(例如.Net基类)添加功能而无法访问代码,那么您将使用扩展方法.扩展方法也有一个约束条件,你不仅需要拥有原始程序集,还必须在程序集中包含扩展方法,这必须由代码的使用者理解.

使用继承将允许您添加,删除或覆盖功能,并确保在构建时始终与类一起使用.


Jos*_*eph 14

当您希望提供应该共享相同行为的各种类型的实现时,应该使用扩展方法,否则将不同.这就是为什么你看到很多接口上使用扩展方法的原因,因为它是一个非常强大的工具,可以确保接口的任何给定实现都具有给定行为的相同实现.

例如,Skip和Take扩展方法.


Ste*_*dit 8

尽可能使用继承而不是扩展方法.

编辑

我更喜欢保持简短,但我当然会回答后续问题.

在可以继承的情况下,也就是说没有密封的类,它几乎总是比扩展方法更好的选择.实际上,这就是womp所引用的最佳实践文档.它有标题,如"警惕扩展方法","在扩展你不拥有的类型之前三思而后行",以及"更喜欢类扩展的接口扩展".换句话说,它只是说出了我的单行代码所做的更多细节.

本文确实给出了详细的原因,但最重要的是,这就是扩展方法的设计方式.他们在游戏后期被添加到语言中作为一些语法糖,以允许MS楔入LINQ而无需返回并重新发明轮子.这是他们有益的典型例子.另一个很好的例子是添加实用程序方法,例如:

public static string FormatWith(this string format, params object[] args)
{ return string.Format(CultureInfo.InvariantCulture, format, args); }
Run Code Online (Sandbox Code Playgroud)

请注意,在这种情况下,扩展方法是实现此附加功能的唯一方法,因为字符串是密封的.

关于继承的构成,虽然这是一个老生常谈,但我没有看到这里的相关性.无论我们是使用扩展方法还是继承,目标都是更改接口以允许其他方法.无论是通过组合,泛型还是其他技术,这种方法的实现方式都是正交的.

  • 赞成合成而不是继承. - http://www.artima.com/lejava/articles/designprinciples4.html (7认同)

Ran*_*pho 8

嗯...你不能总是使用继承.String例如,是一个密封的类.在那些扩展方法确实闪耀的情况下.

通常,扩展方法最适用于您可能放入静态类的小实用程序,但它们针对特定类型的实例进行操作.字符串是一个很好的例子 - 几乎每个人都有自己的小字符串扩展方法来对字符串进行少量操作.

扩展方法的另一个好地方是反对枚举.我几乎总是包含HasFlag针对[Flags]我创建的任何枚举的扩展方法.