次のように C# で定義された基本インターフェイスがあるとします。
interface IBase
{
int Prop1 { get; set }
string Prop2 { get; set }
}
次に、次のような派生インターフェイスがあります。
interface ISub1: IBase
{
int Prop3 { get; set }
}
これらのインターフェイスは、カスタム アプリケーションがコンパイルおよび実行される API アセンブリで定義されます。(アセンブリには、これらのインターフェイスを実装する公開されていないクラスと、インスタンスを取得するためのパブリック ファクトリ メソッドも含まれます)。現存するすべてのコードは を使用しておりISub1
、直接参照する既存のコードはありませんIBase
。ISub2
最終的に のピアとして2 番目の派生インターフェイス を導入する可能性があることを予期して、このように行われましたがISub1
、それが実現しました。残念ながら、 には(Prop1 といくつかの追加の一意のプロパティのみ) をISub2
含めるべきではないことがわかりました。そのため、そのプロパティを に「降格」して、次の改訂されたインターフェイスを作成します。Prop2
ISub1
interface IBase
{
int Prop1 { get; set }
}
interface ISub1: IBase
{
string Prop2 { get; set }
int Prop3 { get; set }
}
interface ISub2: IBase
{
string Prop4 { get; set }
}
消費者がいないことを考えると、IBase
これを免責で実行できるように思われます (そして、Java で実行できると確信しています)。しかし、実行しようとすると、コードのバイナリ互換性の問題に遭遇しました。古いインターフェース定義に対してコンパイルされました。具体的には:
ISub1 s1 = ... // get an instance
s1.Prop2 = "help";
このコードを新しいインターフェイス定義に対して実行すると、次の例外が発生して失敗します。
System.MissingMethodException : メソッドが見つかりません: 'Void MyNamespace.IBase.set_Prop2(System.String)'.
への参照に注意してくださいIBase
。これは、 のように見える呼び出しが、 で実際に導入されISub1.set_Prop2
た場所へのタイトなバインドでコンパイルされているためであると推測されます。Prop2
IBase
この難問から抜け出す方法を教えてくれる人はいますか? つまり、ISub2 の定義が "クリーン" になるようにインターフェイスをリファクタリングする方法はありますか (余分な Prop2 は含まれません)。既存のすべてのアプリケーションを再コンパイルするように要求することは問題外です。