web-dev-qa-db-ja.com

"where T:class、new()"はどういう意味ですか?

次のコード行でwhere T : class, new()の意味を説明していただけますか?

void Add<T>(T item) where T : class, new();
260
Rawhi

これは、汎用パラメーターTの制約です。 class(参照型)でなければならず、パブリックなパラメーターなしのデフォルトコンストラクターが必要です。

つまり、TintfloatdoubleDateTime、またはその他のstruct(値型)にすることはできません。

デフォルトまたはパラメータなしのコンストラクタがある限り、string、またはその他のカスタム参照型にすることができます。

286
NerdFury

これらは一般的な型の制約です。あなたの場合、それらの2つがあります。

where T : class

タイプTは参照タイプ(値タイプではない)でなければならないことを意味します。

where T : new()

タイプTにはパラメーターなしのコンストラクターが必要であることを意味します。この制約があると、コード内でT field = new T();のようなことができます。

次に、コンマを使用して2つを結合して以下を取得します。

where T : class, new()
140
Justin Niessner

ここでT:struct

Type引数は値型でなければなりません。 Nullable以外の任意の値タイプを指定できます。詳細については、「Nullable型の使用(C#プログラミングガイド)」を参照してください。

ここでT:クラス

型引数は、クラス、インターフェイス、デリゲート、または配列型を含む参照型である必要があります。 (下記の注を参照してください。)

where T:new() type引数には、パブリックなパラメーターなしのコンストラクターが必要です。他の制約と組み合わせて使用​​する場合、new()制約は最後に指定する必要があります。

ここでT:[基本クラス名]

Type引数は、指定された基本クラスであるか、そこから派生する必要があります。

ここでT:[インターフェイス名]

Type引数は、指定されたインターフェイスであるか、実装する必要があります。複数のインターフェイス制約を指定できます。制約インターフェイスも汎用的です。

ここでT:

Tに提供される型引数は、Uに提供される引数であるか、それから派生する必要があります。これは、ネイキッド型制約と呼ばれます。

107

classnewは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
}
16
Sergio

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();
        }
    }
13
Brendan

これは、タイプTがクラスでなければならないことを意味しますandは引数を取らないコンストラクタを持っています。

たとえば、これを行うことができる必要があります。

T t = new T();
6
Evan Mulawski

where(C#リファレンス)

New()制約により、コンパイラーは、指定された型引数にアクセス可能なパラメーターレス(またはデフォルト)コンストラクターが必要であることを認識できます

したがって、Tはクラスであり、パラメーターなしでアクセス可能な、またはデフォルトのコンストラクターである必要があります。

5

「どこ」の後に来るのは、宣言したジェネリック型Tに対する制約です。したがって、

  • classは、Tが値型または構造体ではなくクラスであることを意味します。

  • new()は、Tクラスにパブリックなパラメーターなしのデフォルトコンストラクターを定義する必要があることを示します。

3

これは、ジェネリックパラメーターTの「制約」と呼ばれます。つまり、Tは参照型(クラス)でなければならず、パブリックなデフォルトコンストラクターを持たなければならないことを意味します。

1
Josh

これはGenericsメカニズムの一部であり、whereキーワードは、型パラメーターとして使用するために実装する必要のある型に制約を追加します。

1
Peter Lillevold