2011-01-09 17 views
14

ジェネリック制約がどのように機能するかを理解することに問題があります。私はここで重要な何かを逃していると思う。コメントに私の質問をまとめてあり、何らかの説明をしてくれたことに感謝します。参照型と値型であるTに対する一般的な制約はありますか?

//1st example: 

class C <T, U> 
    where T : class 
    where U : struct, T 
{ 
} 
//Above code compiles well, 
//On first sight it looks like U might be reference type and value type 
//at the same time. The only reason I can think of, is that T may be an 
//interface which struct can implement, Am I correct? 

//2nd example 

class CC<T, U> 
    where T : class, new() 
    where U : struct, T 
{ 
} 

//I added also a reguirement for parameterless constructor 
//and, much to my surprise, it still compiles what is 
//a bit inexplicable for me. 
//What 'U' would meet the requirement to be 
//value type, reference type and have a contructor at the same time? 

答えて

12

何も問題はありません。さんはconstraints on the type parametersの定義を見てみましょう:

  • T : classを - 型引数Tは任意のクラス、インターフェイス、デリゲート、または配列型を含め、参照型でなければなりません。
  • U : struct - 型引数Uは値型でなければなりません。
  • U : T - Uがあるか、クラスT.

から派生しなければならないタイプの引数は、だから、あなたがする必要があるすべては、参照型から派生した値のタイプを見つけることです。最初はそれは不可能に聞こえるかもしれませんが、あなたは少し難しくあなたがすべての構造体は、クラスobjectから派生することを覚えているだろうと思い、そうだとすれば、これは、両方のあなたの例については、正常に動作します:しかし、あなたが、その後structclassを交換する場合

new C<object, int>(); 

コンパイルされません:

// Error - Type parameter 'T' has the 'struct' constraint so 'T' 
//   cannot be used as a constraint for 'U' 
class C<T, U> 
    where T : struct 
    where U : class, T 
{ 
} 
+1

はい?そして? Tのためにそれを指定しました。これはオブジェクトコンストラクタと一致します。それで大丈夫です。 –

+0

はい、あなたは間違っています。 @Mark Byersあなたは、すべての構造体が 'object'から派生したと言っています。だから私は 'CS T:class {}'のようなコード 'CS obj = new CS ();'は動作しませんでしたが、 'DateTime'はオブジェクトにキャスト可能です。 – nan

+0

@Andrzej Nosal:はい、制約 "T:class"は* Tがオブジェクト*にキャスト可能であるという意味ではないためです。 * Tは参照型でなければなりません*。 DateTimeは参照型ではありません。 –

関連する問題