我目前正在学习C#扩展方法。我在几个地方读到,向类中添加成员会降低使用这些类的代码的向后兼容性。
和Troelson的Pro C#书第418页。
我担心这对我没有意义。当然,任何在添加额外成员之前使用这些类的实例的代码(不使用扩展方法,只需将它们添加到类中),仍然能够像调用所有旧的方法,属性,字段和构造函数一样之前,因为他们没有改变。即使新成员可以更改对象的状态,也不会在旧代码中调用它们,因此代码向后兼容。
我在这里看不到什么?
答案 0 :(得分:2)
以下添加新方法的一种可能方法实际上可能会破坏客户端代码...
void Main()
{
var oldFoo = new OldFoo();
var oldResult = oldFoo.Calculate(2, 2); // 4
var newFoo = new NewFoo();
var newResult = newFoo.Calculate(2, 2); // 0
}
public class OldFoo
{
public int Calculate(params int[] values)
{
return values.Sum();
}
}
public class NewFoo
{
public int Calculate(params int[] values)
{
return values.Sum();
}
public int Calculate(int value1, int value2)
{
return value1 - value2;
}
}
这是另一种方式,专门处理扩展方法......
最初,客户定义了一种扩展方法,使Foo
能够Combine
:
void Main()
{
var foo = new Foo();
var result = foo.Combine(2, 2); // "22"
}
public static class Extensions // added by client
{
public static string Combine(this Foo foo, params int[] values)
{
return string.Join(string.Empty, values.Select(x => x.ToString()));
}
}
public class Foo { }
稍后,Foo
的开发人员向该类添加了一个新的Combine
方法:
void Main()
{
var foo = new Foo();
var result = foo.Combine(2, 2); // 4
}
public static class Extensions
{
public static string Combine(this Foo foo, params int[] values)
{
return string.Join(string.Empty, values.Select(x => x.ToString()));
}
}
public class Foo
{
public int Combine(params int[] values)
{
return values.Sum();
}
}
请注意,新的Combine
实例方法会有效阻止扩展方法或隐藏。
答案 1 :(得分:-1)
现实世界的比喻可能有所帮助。想想它就像机械一样。想象一下有人设计了一种引擎,人们开始使用它作为某些设备的基础,比如收割机。如果发动机设计师决定燃油滤清器会有所帮助并加上它,那么它可能会破坏收割机的设计,因为这种设计可能会在现在由新燃油滤清器占据的空间内放置一些东西。
添加新成员(燃油泵)降低了向后兼容性。收割机设计基于历史上的落后版本。
更基于编程的示例:应用程序设计人员为他的应用程序创建一个以特定方式运行的解析器。发布后,它发现解析器没有正确实现某些不常见条件的规范。发布了一个正确实现规范的新版本,但添加了一个标志来提供先前的行为。