2016-05-02 3 views
0

です:このコードはうまく機能ジェネリックパラメータを確認し、私は辞書のキーとして一般的なパラメータを使用して、一般的な方法で持っている具体的なタイプ

public void MyMethod<T>(IEnumerable<T> myCollection) where T : IMyInterface 
{ 
    var smthg = MyDictionary[typeof(T)]; 
    //... 
} 

を。しかし、もちろん、あなたがそのようにそれを呼び出す場合:

MyMethod(myCollectionOfT.Cast<IMyInterface>()); 

TIMyInterfaceIMyInterfaceを実装していないクラス)になり、辞書が(正常)キーを持っていません。

問題が発生したときに、私は簡単に例外がスローされていることができます。

if (typeof(T) == typeof(IMyInterface)) throw new ArgumentException("The generic parameter should be strongly typed.", "T"); 

をしかし、あなたの呼び出しは、クラスの代わりにインターフェイスを使用する場合、コンパイル時エラーを持つ方法(制約または何か)がありますそれを実装している?

編集:

Dスタンレーは、溶液が得られた:new()制約はTインターフェイスないことgaranteeう。

+0

あなたはそれがただインターフェイスではないことを望みますか?もしそれが 'IMyInterface'を拡張した_different_インタフェースだったらどうでしょうか? –

+7

インタフェースを使用できないようにする唯一の制約は、具体的な型にパブリックのパラメータのないコンストラクタが必要であることを要求する 'new()'です。 –

+2

また、辞書であなたは何をしていますか?下のコードが本当に_generic_でない場合は、ジェネリックを使用していると思います。代わりに過負荷が必要なのでしょうか? –

答えて

0

参照型を扱う場合は、 classという制約を使用できます。 編集:実際には、「ちょうど」のインターフェイスにも一致します。しかたがない。

これは実際には機能上の非仮想的な方法でインターフェイスを(より広い意味で)使っています。どうすればいいですか?

MyMethod(MyListOfDerivedClass.Cast<MyBaseClass>()) 

インターフェイスと継承の設計に違反しているので、独自のルールが破られていないことを確認する必要があります。あなたはそれらを違反しているので、コンパイラや通常のOOPデザインルールに依存することはできません。

タイプIEnumerable<IMyInterface>の任意の引数を受け入れるように汎用メソッドを設計すると、IMyInterfaceの実装は有効であるはずです。同じように、列挙型のアイテムが異なるタイプのものであるかどうかは関係ありません。すべてがIMyInterfaceを適切に実装している限りです。ジェネリックかどうかにかかわらず、どのメソッドでも同じことです。あなたがやっていることはControlを受け入れる方法を有することに似ていますが、実際にLabelButtonを渡す場合にのみ動作し、LabelまたはButtonからを得種類を含め、何のために失敗しました。

+2

'class'はインターフェイスの使用を妨げません。それは型が_reference type_であることを保証するだけです。 –

+0

@DStanley Chmm、そうです。つまり、 'struct'をインターフェースとして渡すと面白いことです:/ – Luaan

-1

あなたはMSDN Constraints on Type Parameters 編集に応じて、このコード

public void MyMethod<T>(IEnumerable<T> myCollection) where T : IMyInterface, class, new() 
{ 
    var smthg = MyDictionary[typeof(T)]; 
    //... 
} 

のようなものを使用することができます。 クラスはTが参照型でなければならないことを意味します。これは、どのクラス、インタフェース、デリゲート、または配列型にも当てはまります。したがって、あなたのコンストラクタがpublicであればnew()を使ってTがクラスであることを確認することができます。

+2

' class'は、あなたが型パラメーターとしてインターフェースを使用するのを妨げません。それは型が_reference type_であることを保証するだけです。 –

+0

DStanleyが正しいです。クラスは動作しません。 – krimog

関連する問題