次のようなクラスがあるとしましょう:
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 Substitution の意味で本当に資格があるとは考えていないためです...これは、構成による私の拡張クラスの使用が非常に限られていることを意味します。
したがって、これを修正する唯一の方法は、元の 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 を公開して、時々渡すことができるようにすることですが、それは面倒です。