扩展方法和源代码前进了兼容性
我想解决这个问题使用扩展方法和未来发展类接口的maginification的(现在假设,但未来propably实)。扩展方法和源代码前进了兼容性
例子:
/* the code written in 17. March 2010 */
public class MySpecialList : IList<MySpecialClass> {
// ... implementation
}
// ... somewhere elsewhere ...
MySpecialList list = GetMySpecialList(); // returns list of special classes
var reversedList = list.Reverse().ToList(); // .Reverse() is extension method
/* now the "list" is unchanged and "reveresedList" has same items in reversed order */
/* --- in future the interface of MySpecialList will be changed because of reason XYZ*/
/* the code written in some future */
public class MySpecialList : IList<MySpecialClass> {
// ... implementation
public MySpecialList Reverse() {
// reverse order of items in this collection
return this;
}
}
// ... somewhere elsewhere ...
MySpecialList list = GetMySpecialList(); // returns list of special classes
var reversedList = list.Reverse().ToList(); // .Reverse() was extension method but now is instance method and do something else !
/* now the "list" is reversed order of items and "reveresedList" has same items lake in "list" */
我的问题是:有没有一些方法如何防止这种情况下(我没找到)?如果现在如何防止它,有没有办法找到像这样的可能的问题?如果现在如何找到可能的问题,我是否应该禁止使用扩展方法?
谢谢。
编辑:
此致答案是有用的。 我可以在代码中找到扩展方法吗?和/或我可以找到代码中的哪些地方使用实例方法,但存在具有相同签名的扩展方法?
它看起来像你所描述的是以下情况
- 在你的产品
MySpecialList
的V1没有Reverse
方法,以便于Reverse
绑定到同一名称的扩展方法的所有调用 - 在V2您的产品
MySpecialList
获得Reverse
方法,现在所有先前绑定到扩展方法的绑定都会绑定到实例方法。
如果您想在实例/扩展方法窗体中调用Reverse,则无法防止此操作,因为它是设计的行为。如果扩展方法至少与扩展方法版本一样好,那么实例方法将总是优先于扩展方法。
100%防止这种情况的唯一方法是将扩展方法称为静态方法。例如
ExtensionMethods.Reverse(list);
的结合与产品的新版本的新方法,这一问题不仅仅局限于扩展方法(虽然问题可能是一个有点差)。有很多事情可以做,以一个类型改变方式方法结合会受到影响,如实现一个新的接口,继承或添加新的转换
在这种特定情况下我认为,扩展方法返回一个新的反向列表(而不是反向列表)不应该被称为“反向”,但应该是getReversedList()或其他类似的。
但你的观点是正确的(约无副作用的扩展方法得到不经意间的副作用引起本地方法代替);命名约定可能是一个好方法,但是,这是不使用扩展方法不加区分(但不足以禁止它们)的原因。
这就是我们编写单元测试的原因。
首先写入扩展方法。准确地命名它们。所以总有一天,如果一个扩展方法在同名的类中被实现为一个真正的方法,那么这是一个很好的机会,它和扩展方法的功能相同,并且没有任何中断。其次,通过单元测试,你很快就会看到破坏了什么,并且因为扩展方法不再被调用而被破坏,因为类现在拥有一个拥有该名称的自己的方法。鉴于此,您可以选择重命名您的方法,将您的扩展方法称为静态方法,或者重新编写代码以正确使用新方法。
是的,我的意思是完全一样的情况。 如果我理解正确,最正确的方法是使用扩展方法,如静态方法,不使用扩展方法? 如何在代码审查中发现,指定的代码没有使用扩展方法? – TcKs 2010-03-17 16:48:53
我不认为Jared说扩展方法的调用就好像它们是普通的静态方法是正确的;他只是说这是完全避免你所描述的风险的唯一途径 - 但这种风险无论如何都不是完全可以避免的。 – 2010-03-17 16:52:23
@JacobM正确。 – JaredPar 2010-03-17 17:04:43