假设我有一个像这样的类(class):
public sealed class Foo
{
public void Bar
{
// Do Bar Stuff
}
}
我想对其进行扩展以添加扩展方法无法实现的功能....我唯一的选择是composition:
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,但不能在 super Foo中通过,因为C#不知道SuperFoo确实确实符合Liskov替代意义……这意味着我通过组合进行的扩展类的使用非常有限。
因此,解决此问题的唯一方法是希望原始的API设计人员留下一个周围的接口(interface):
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)
现在,由于通用接口(interface),C#理解了SuperFoo和Foo之间的关系,一切都很好。
最大的问题是.NET密封了很多类,这些类有时会很容易扩展,并且它们通常不实现公共(public)接口(interface),因此采用Foo的API方法将不接受SuperFoo,并且您不能添加重载。
因此,对于那里的所有乐迷来说...。如何克服这个限制?
我唯一想到的是公开公开内部Foo,以便您可以偶尔通过它,但这似乎很困惑。
最佳答案
恐怕简短的答案是,您不能不执行所需的操作,即传递组合的实例变量。
您可以让允许对该类型进行隐式或显式强制转换(其实现只是通过组合实例),但这将使IMO变得非常邪恶。
sixlettervariable的答案是好的,我不会重新介绍它,但是如果您指出了您希望扩展的类(class),我们可能会告诉您为什么他们阻止了它。