2011-10-03 4 views
15

私はこのような機能を持っている:どのようにクラスのリストをインターフェイスのリストに渡す?

DoSomething(List<IMyInterface>) 

IMyInterfaceというのインタフェースであり、MyClassのは、このインタフェース クラスMyClassのを実装するクラスです:IMyInterfaceという

私はDoSomething(List<MyClass>)を呼び出し、それが動作しません見えます。 クラスのリストを関数のパラメータとしてクラスのインターフェイスのリストに渡すにはどうすればよいですか?ありがとう!

+0

あなたのコードは何ですか? – talnicolas

答えて

26

コードは単にIEnumerable<>インターフェースは共変である以下

DoSomething(IEnumerable<IMyInterface> sequence) 
DoSomething<T>(IEnumerable<T> sequence) where T : IMyInterface 

のいずれかにあなたの方法を変更(追加、削除、またはインデックスでアクセスしていない)メソッド内でシーケンスを反復された場合(AS .NET 4)(最初のオプション)。または、C#3を使用している場合は後者の署名を使用できます。

それ以外の場合は、インデックス処理が必要な場合は、渡す前にリストを変換します。呼び出しでは、後者の署名はあなたができるようになる何

// invocation using existing method signature 
DoSomething(yourList.Cast<IMyInterface>().ToList()); 

// or updating method signature to make it generic 
DoSomething<T>(IList<T> list) where T : IMyInterface 

がある可能性がありますもサポートすることで追加するか(呼び出し場所で目に見える)リストに削除し、そしてそれはまた、あなたがせずにリストを使用できるようになり最初にそれをコピーします。

でも、あなたがしていることがすべてループの中で繰り返されているのであれば、私はメソッドIEnumerable<>を好むでしょう。

+0

インデックスされた操作と削除の場合、 'DoSomething (IList list)ここでT:IMyInterface'も機能しますか? (リストをコピーする必要はありません) – millimoose

+0

@Sli、はい、彼はメソッドを汎用にすることができます。私は一般的なオプションを表示するように更新しました。 –

+0

代わりに、インターフェイスIReadableList を定義し、IList の両方を実装するラッパークラスを記述することもできます。しかし、残念ながら、他のコードはラッパークラスを使用するように変更する必要があります。 List からListWrapper への変換を広げることを定義できますが、これは多少ぎこちなくなり、List がIReadableList を実装するもの(ListWrapper )に変換できることをシステムが認識するのに役立ちません。 – supercat

7

リストは変更可能であるため、これは一般的に安全ではありません。

void Foo(List<IMyInterface> list) 
{ 
    IMyInterface x = new MyOtherClassWhichAlsoImplementsIMyInterface(); 
    list.Add(x); 
} 

を今すぐあなたのList<MyClass>MyClassないクラスのインスタンスが含まれています:あなたは、その後、彼らは誰かList<IMyInterface>としてList<MyClass>への参照渡しとします。これは型の安全に違反します。 (他の答えとして、ListのIEnumerable<>インターフェイスだけを渡すことでこの問題を回避できます。これは、読み取り専用アクセスを提供するので安全です)。

詳細については、Using Variance in Interfaces for Generic Collections on MSDNを参照してください。 a good summary of covariance and contravariance and various C# features that support itも参照してください。

0

リストを調べる必要がある場合は、IEnumerableを使用してメソッドを宣言します。リストに要素を追加する場合は、タイプセーフではなく、結果としてC#で許可されないことがあります。

関連する問題