评估在C#中使用扩展方法的成本/好处=> 3.0

在什么情况下(使用场景)你会选择编写扩展而不是对对象进行子分类?

<全面披露:我不是MS员工; 我亲自不认识Mitsu Furota; 我确实知道这里提到的开放源代码Componax库的作者,但我与他无任何商业往来; 我没有创建或计划使用扩展创建任何商业产品:总而言之:这篇文章来源于纯粹的智力好奇心,与我试图(不断)意识到“最佳实践”相关>

我发现扩展方法“很酷”的想法,很明显,您可以在他们的Mitsu Furota(MS)博客链接文本中的许多示例中完成与他们“遥远”的事情。

一位私人朋友编写了开放源码的Componax library链接文本,并且在那里有一些非凡的设施; 但他完全掌握了他的小公司,完全控制了代码准则,并且每行代码都“通过他的手”。

虽然这是我的猜测:我认为/猜想其他问题可能会在大中型软件团队使用扩展的情况下发挥作用。

在链接文本中查看MS的准则,您会发现:

一般来说,你可能会比实现自己的扩展方法更经常地调用扩展方法。 ...一般来说,我们建议您谨慎实施扩展方法,并且只在必要时才执行。 只要有可能,必须扩展现有类型的客户端代码应通过创建从现有类型派生的新类型来实现。 有关更多信息,请参见继承(C#编程指南)。 ...当编译器遇到方法调用时,它首先在类型的实例方法中查找匹配项。 如果找不到匹配项,它将搜索为该类型定义的任何扩展方法,并绑定到它找到的第一个扩展方法。

在女士的链接文本中:

扩展方法不存在特定的安全漏洞。 它们不能用于模拟类型上的现有方法,因为所有名称冲突都会被解析,以支持类型本身定义的实例或静态方法。 扩展方法无法访问扩展类中的任何私有数据。

对我来说显而易见的因素包括:

  • 我假设你不会写一个扩展,除非你期望它被非常普遍和频繁地使用。 另一方面:你不能说分类的同样的东西吗?

  • 知道我们可以将它们编译为一个单独的dll,然后添加编译后的dll并引用它,然后使用扩展:“很酷”,但是这样做是否能“平衡”编译器固有的成本,首先必须检查如果实例方法如上所述进行定义。 或者在使用静态调用方法来确保扩展被调用而不是实例定义的情况下,如果出现“名称冲突”,那么代价是多少?

  • 如何频繁使用扩展会影响运行时性能或内存使用:我不知道。

    所以,我会很感激你的想法,或者知道如何/何时做或不做,使用扩展,而不是子类。

    谢谢,比尔


    我对他们最大的用处是扩展封闭的第三方API。

    大多数情况下,当一个软件开发人员在Windows上提供API时,他们越来越倾向于.NET的可扩展性。 我喜欢这样做,因为我更愿意依赖我自己的方法,以后我可以修改它们,并在它们改变它的情况下作为其API的全局入口点。

    以前,当必须这样做时,我无法继承API对象,因为它被密封或者什么东西,我会依赖Adapter模式来创建自己的类来包装它们的对象。 这是一个功能性的,但不是很优雅的解决方案。 扩展方法为您提供了一种将更多功能添加到您无法控制的功能的漂亮方法。

    其他许多人最喜欢的是LINQ!

    没有IEnumerable提供的扩展方法,LINQ将无法实现。

    人们喜欢它们的原因是因为它们使代码更具可读性。

    我注意到扩展方法(包括我自己)的另一个MAJOR用法是使代码更具可读性,并使其看起来好像执行某些操作的代码属于它应该在的位置。 它也摆脱了我见过很多次的可怕的“Util”静态神级。 什么看起来更好... Util.DecimalToFraction(decimal value);value.ToFraction(); ? 如果你像我一样,后者。

    最后,有些人认为“静态方法”是EVIL!

    许多“优秀程序员”会告诉你,你应该尽量避免使用静态方法,尤其是那些使用大量单元测试的方法。 静态方法在某些情况下很难测试,但如果使用得当,它们并不是邪恶的。 虽然扩展方法是静态的......但它们看起来并不像这样。 这允许你将这些静态方法从你的类中移出来,并放到它们真正应该附加到的对象上。

    关于表现..

    扩展方法与调用静态方法并没有什么不同,它将扩展的对象作为参数传递......因为这是编译器将其转化为的东西。 最棒的是你的代码看起来很干净,它可以做你想做的事情,编译器为你处理肮脏的工作。


    我使用扩展方法来改进类的功能,而不增加类的复杂性 。 您可以保持简单的课程,然后稍后添加重复性作业作为扩展。

    Min()Max()扩展方法就是很好的例子。 您可以轻松地声明一个私有方法来计算这些方法,但扩展方法提供了更好的可读性,使得整个项目的功能可用,并且不需要使数组变得更加复杂。


    采用子分类方法和扩展方法需要一些事情是真实的

  • 该类型必须是可扩展的(未密封的)
  • 所有创建类型的地方都必须支持排序的工厂模式,否则其他代码只会创建基本类型。
  • 除了使用C#3.0+编译器外,添加扩展方法只需要其他任何东西。

    但最重要的是,继承层次应该代表一种是一种关系。 我不觉得为真正表达这种关系的类增加1或2个新的方法/行为。 它反而增加了现有的行为。 包装类或扩展方法更适合这种情况。

    链接地址: http://www.djcxy.com/p/17441.html

    上一篇: evaluating cost/benefits of using extension methods in C# => 3.0

    下一篇: What Advantages of Extension Methods have you found?