假设我有一个像这样的类(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),我们可能会告诉您为什么他们阻止了它。

10-08 18:53