假设我有这样的课程:
public sealed class Foo
{
public void Bar
{
// Do Bar Stuff
}
}
而且我想扩展它以添加超出扩展方法可以做的东西......我唯一的选择是组合:
public class SuperFoo
{
private Foo _internalFoo;
public SuperFoo()
{
_internalFoo = new Foo();
}
public void Bar()
{
_internalFoo.Bar();
}
public void Baz()
{
// Do Baz Stuff
}
}
虽然这可行,但工作量很大......但是我仍然遇到了一个问题:
public void AcceptsAFoo(Foo a)
我可以在这里传入一个 Foo,但不能传入一个超级 Foo,因为 C# 不知道 SuperFoo 在 Liskov 替换意义上确实符合条件......这意味着我通过组合扩展类的用途非常有限。
所以,修复它的唯一方法是希望原始 API 设计者留下一个接口:
public interface IFoo
{
public Bar();
}
public sealed class Foo : IFoo
{
// etc
}
现在,我可以在 SuperFoo 上实现 IFoo(因为 SuperFoo 已经实现了 Foo,只是改变签名的问题)。
public class SuperFoo : IFoo
在完美世界中,使用 Foo 的方法会使用 IFoo 的:
public void AcceptsAFoo(IFoo a)
现在,由于通用接口,C# 理解了 SuperFoo 和 Foo 之间的关系,一切都很好。
最大的问题是 .NET 封装了许多偶尔会很好扩展的类,而且它们通常不实现通用接口,因此采用 Foo 的 API 方法不会接受 SuperFoo 并且您不能添加重载.
所以,对于所有的作曲爱好者来说......你如何绕过这个限制?
我唯一能想到的就是将内部的 Foo 公开,这样你可以偶尔通过它,但这似乎很乱。