.netでは、基本クラスでの部分的なインターフェイス実装が許可されていません。緩和策として、私は3つの代替ソリューションを用意しました。リファクタリング、コンパイル/ランタイムエラー、可読性の点で、より普遍的なものを決定するのを手伝ってください。 最初にいくつかのコメント。基本クラス/抽象クラスでのC#最適な部分インターフェイス実装
- もちろん、オブジェクトをIFooにキャストし、コンパイラの警告なしで任意のメソッドを呼び出すことができます。しかし、それは論理的ではありません、あなたはそれを普通にやりません。この構成は、リファクタリングの結果としては起こりません。
- 最大限の分離が必要です。直接クラス契約(パブリックメソッドとプロパティ)は、インタフェースの実装と分離する必要があります。私はオブジェクトインターアクションを分離するためにインターフェイスを多く使用しています。
マイ比較:
- BaseClass1/MyClass1:
- 詐欺:IFooのそれぞれ実装されていないメソッドのBaseClass1で仮想抽象を作成する必要があります。
- con:追加メソッドのラップ - 実行時のわずかな生産性への影響。
- BaseClass2/MyClass2:
- 詐欺:MyClass2における方法2の無実装がない場合はコンパイラの警告。代わりにランタイム例外。ユニットテストのカバレッジが悪いリファクタリングは、コードを不安定にする可能性があります。
- con:子クラスからの直接的なメソッド呼び出しを防ぐために、廃止された構造体を追加する必要があります。
- con:Method2はBaseClass1のため公開されているので、今はclass contractの一部です。 IFoo経由ではなく、直接呼び出しを防ぐために「廃止」構造体を置かなければなりません。
- BaseClass3/MyClass3:
- プロ:(#2と比較すると)。より読みやすい。 MyClass2.Method2はオーバーライドされたメソッドだけでなく、IFooの実装であることがわかります。
public interface IFoo
{
void Method1();
void Method2();
}
public abstract class BaseClass1 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
void IFoo.Method2()
{
IFooMethod2();
}
protected abstract void IFooMethod2();
}
public class MyClass1 : BaseClass1
{
[Obsolete("Prohibited direct call from child classes. only inteface implementation")]
protected override void IFooMethod2()
{
//some implementation
}
}
public abstract class BaseClass2 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
[Obsolete("Prohibited direct call from child classes. only inteface implementation")]
public virtual void Method2()
{
throw new NotSupportedException();
}
}
public abstract class MyClass2 : BaseClass2
{
public override void Method2()
{
//some implementation
}
}
public abstract class BaseClass3 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
void IFoo.Method2()
{
throw new NotSupportedException();
}
}
public abstract class MyClass3 : BaseClass3, IFoo
{
void IFoo.Method2()
{
//some implementation
}
}
これは、実装しようとしている**非常に厄介なパターンです。あなたが言った* "。NETは基本クラスで部分的なインターフェイスの実装を許可していません" * - その理由があります。クライアントコードの種類は、**インターフェース**を実装しているものがあります。おそらく... **インターフェースを実装しています**。サポートされていないメソッドの例外をスローすることは、もちろんです。*非常に*悪いコードの臭いです... – Yuck
Yuckと同意します。あなたが 'IFoo'型の変数を持っているなら、実際には' IFoo'のすべてのメソッドが実装され、利用可能であると期待しています。そのためのインターフェースが作られています。 – ken2k
MyClass1のみがインターフェイスを完全に実装している必要があります。それはそうです。問題は、複数の子クラスがあることです(私はこれまで言及していませんでした)、それぞれIFooを実装する必要があります。基本クラスがなければ、Method1の実装をコピー/貼り付けする必要があります。これはすべての子クラスに対して等しくなります。これは私が避けようとしていることです。しかし、Method2実装は子クラスでは異なるので、Method1とMethod2の両方を実装するクラスを1つだけ持つことはできません。 – user1194528