「インターフェイス IFoo および IBar を実装するオブジェクトを期待するメソッド」を表現したいとしましょう。何かのようなもの:
void Method(IFoo+IBar param);
C# を使用してこれをどのように言えますか?
(構文構造はありますか? または、おそらく適切な慣用句はありますか?)
試み
インターフェイスを導入します。
interface IFooBar : IFoo, IBar {}
void Method(IFooBar param);
これは悪いことであり、考えたことを後悔しています:-) 一見問題ないように見えますが、悲しいことに、ここにあってはならない依存関係が静かに導入されます。
が存在する唯一の理由は、のインターフェースのIFooBar
一部になることです。Method
したがって、Method
のパラメーターとして使用されるオブジェクトのクラスは、このメソッド (およびそのインターフェイス) が存在することを認識している必要があります。それ以外の場合はそうではありません。IFoo と IBar を実装するすべてのクラスは、IFooBar も実装するように変更する必要があります (おそらく、新しいアセンブリを知る必要があります)。これは非常に非現実的であり、変更できない場合は不可能ですらあります。
不要な依存 = ダメ。
回避策
静的型付けをあきらめる:
void Method(object param)
{
if (!param is IFoo)
throw new ArgumentException("IFoo not supported", "param");
if (!param is IBar)
throw new ArgumentException("IBar not supported", "param");
// ...
}
(または: 署名で 1 つのタイプを定義し、他のタイプを動的にチェックします。1 つが最も重要な場合は望ましいですが、さらに混乱を招きます)
正しく動作しますが、実行時に動作します (コンパイル時のチェックはありません)。必死にドキュメントを必要とします (そしてそれを読むために誰もが)。
また、関数パラメーターでのみ実用的です。フィールドで使用しようとすると、キャストでコードが大幅に肥大化します。
この状況の実際のケースは?たとえばIList<Foo>
+ INotifyCollectionChanged
.