次のコード行でwhere T : class, new()
の意味を説明していただけますか?
void Add<T>(T item) where T : class, new();
これは、汎用パラメーターT
の制約です。 class
(参照型)でなければならず、パブリックなパラメーターなしのデフォルトコンストラクターが必要です。
つまり、T
をint
、float
、double
、DateTime
、またはその他のstruct
(値型)にすることはできません。
デフォルトまたはパラメータなしのコンストラクタがある限り、string
、またはその他のカスタム参照型にすることができます。
これらは一般的な型の制約です。あなたの場合、それらの2つがあります。
where T : class
タイプT
は参照タイプ(値タイプではない)でなければならないことを意味します。
where T : new()
タイプT
にはパラメーターなしのコンストラクターが必要であることを意味します。この制約があると、コード内でT field = new T();
のようなことができます。
次に、コンマを使用して2つを結合して以下を取得します。
where T : class, new()
ここでT:struct
Type引数は値型でなければなりません。 Nullable以外の任意の値タイプを指定できます。詳細については、「Nullable型の使用(C#プログラミングガイド)」を参照してください。
ここでT:クラス
型引数は、クラス、インターフェイス、デリゲート、または配列型を含む参照型である必要があります。 (下記の注を参照してください。)
where T:new() type引数には、パブリックなパラメーターなしのコンストラクターが必要です。他の制約と組み合わせて使用する場合、new()制約は最後に指定する必要があります。
ここでT:[基本クラス名]
Type引数は、指定された基本クラスであるか、そこから派生する必要があります。
ここでT:[インターフェイス名]
Type引数は、指定されたインターフェイスであるか、実装する必要があります。複数のインターフェイス制約を指定できます。制約インターフェイスも汎用的です。
ここでT:
Tに提供される型引数は、Uに提供される引数であるか、それから派生する必要があります。これは、ネイキッド型制約と呼ばれます。
class
&new
は2 ジェネリック型パラメーターT
の制約 です。
それぞれ:
class
Type引数は参照型である必要があります。これは、クラス、インターフェイス、デリゲート、または配列タイプにも適用されます。
new
Type引数には、パブリックなパラメーターなしのコンストラクターが必要です。他の制約とともに使用する場合、new()制約は最後に指定する必要があります。
これらの組み合わせは、タイプT
が 参照タイプ ( 値タイプ であってはならない)でなければならず、パラメーターのないコンストラクターを持つ必要があることを意味します。
例:
struct MyStruct { } // structs are value types
class MyClass1 { } // no constructors defined, so the class implicitly has a parameterless one
class MyClass2 // parameterless constructor explicitly defined
{
public MyClass2() { }
}
class MyClass3 // only non-parameterless constructor defined
{
public MyClass3(object parameter) { }
}
class MyClass4 // both parameterless & non-parameterless constructors defined
{
public MyClass4() { }
public MyClass4(object parameter) { }
}
interface INewable<T>
where T : new()
{
}
interface INewableReference<T>
where T : class, new()
{
}
class Checks
{
INewable<int> cn1; // ALLOWED: has parameterless ctor
INewable<string> n2; // NOT ALLOWED: no parameterless ctor
INewable<MyStruct> n3; // ALLOWED: has parameterless ctor
INewable<MyClass1> n4; // ALLOWED: has parameterless ctor
INewable<MyClass2> n5; // ALLOWED: has parameterless ctor
INewable<MyClass3> n6; // NOT ALLOWED: no parameterless ctor
INewable<MyClass4> n7; // ALLOWED: has parameterless ctor
INewableReference<int> nr1; // NOT ALLOWED: not a reference type
INewableReference<string> nr2; // NOT ALLOWED: no parameterless ctor
INewableReference<MyStruct> nr3; // NOT ALLOWED: not a reference type
INewableReference<MyClass1> nr4; // ALLOWED: has parameterless ctor
INewableReference<MyClass2> nr5; // ALLOWED: has parameterless ctor
INewableReference<MyClass3> nr6; // NOT ALLOWED: no parameterless ctor
INewableReference<MyClass4> nr7; // ALLOWED: has parameterless ctor
}
new():new()制約を指定することは、タイプTがパラメーターなしのコンストラクターを使用する必要があることを意味するため、そこからオブジェクトをインスタンス化できます-参照 デフォルトのコンストラクター
class:Tは参照型である必要があるため、int、float、double、DateTime、または他の構造体(値型)にはできません。
public void MakeCars()
{
//This wont compile as researchEngine doesn't have a public constructor and so cant be instantiated.
CarFactory<ResearchEngine> researchLine = new CarFactory<ResearchEngine>();
var researchEngine = researchLine.MakeEngine();
//Can instantiate new object of class with default public constructor
CarFactory<ProductionEngine> productionLine = new CarFactory<ProductionEngine>();
var productionEngine = productionLine.MakeEngine();
}
public class ProductionEngine { }
public class ResearchEngine
{
private ResearchEngine() { }
}
public class CarFactory<TEngine> where TEngine : class, new()
{
public TEngine MakeEngine()
{
return new TEngine();
}
}
これは、タイプT
がクラスでなければならないことを意味しますandは引数を取らないコンストラクタを持っています。
たとえば、これを行うことができる必要があります。
T t = new T();
New()制約により、コンパイラーは、指定された型引数にアクセス可能なパラメーターレス(またはデフォルト)コンストラクターが必要であることを認識できます
したがって、T
はクラスであり、パラメーターなしでアクセス可能な、またはデフォルトのコンストラクターである必要があります。
「どこ」の後に来るのは、宣言したジェネリック型Tに対する制約です。したがって、
classは、Tが値型または構造体ではなくクラスであることを意味します。
new()は、Tクラスにパブリックなパラメーターなしのデフォルトコンストラクターを定義する必要があることを示します。
これは、ジェネリックパラメーターTの「制約」と呼ばれます。つまり、Tは参照型(クラス)でなければならず、パブリックなデフォルトコンストラクターを持たなければならないことを意味します。
これはGenericsメカニズムの一部であり、whereキーワードは、型パラメーターとして使用するために実装する必要のある型に制約を追加します。