1

Java について私がイライラすることの 1 つは、ジェネリック型引数のコンパイル時の変換のひどい実装です。

C# の実装がはるかに優れていることを観察して理解することはできますが、それがどのように機能するかについては混乱しています。

基本的に、どのように言えますか:

T t = new T()

T の型がわからないため、コンストラクターの引数の要件がわからない場合は?

私は見えます

Class<T> cl = T.class

また

T[] tarr = new T[0]

しかし、T を構築するための要件を知らなければ、T の新しいインスタンスを実際に作成する方法がわかりません。

4

4 に答える 4

4

new T();T がプレーンなパラメーターなしのパブリック コンストラクターを持つように制約されている場合にのみ実行できます。たとえば、次のようになります。

public class Foo<T> where T : new() {
    private myT = new T();
}

さらに、他の種類のコンストラクターが存在することを指定する方法はありません。これは不可能です:

// Doesn't work
public class Foo<T> where T : new(String, Int) {
    private myT = new T("Foo", 5);
}

他のポイントとして、実行時に T の型を取得する方法は次のとおりです。

var tType = typeof(T);

の配列を作成Tしても、実際にはインスタンスは作成されません (Tが値型でない限り、その型のデフォルト値が作成されます)。

// Space for 32 T's, but nothing in the array.
// If T is a value type, like an int for instance, 
// each one would have the default value (0 for int, for example)
var arrayOfT = new T[32];
于 2012-06-04T18:50:52.120 に答える
2

実際には、コンパイラーにパラメーターなしのコンストラクターを強制Tするように依頼して、できることをコンパイラーに知らせますnew T()。例えば:

class Test<T>
{
    T Create()
    {
        return new T();
    }
}

Tコンパイラーは、それが抽象クラスではなく、デフォルトのコンストラクターを持つことを確認できないため、コンパイルされません。これを機能させるには、T の実数型に制約を追加する必要があります。

class Test<T> where T : new()

これで、コンパイラはTデフォルトのコンストラクターを持つ非抽象クラスになるように強制されます。たとえば、指定された型が抽象型であるため、次のコードは有効ではありません。

abstract class AnotherTest
{
    public void Test()
    {
        Test<Derived> test = new Test<Derived>();
    }
}

繰り返しますが、デフォルトのコンストラクターなしでクラスを使用しようとすると、コンパイラーはエラーを出します:

class AnotherTest
{
    public AnotherTest(string someParameter)
    {
    }

    public void Test()
    {
        Test<Derived> test = new Test<Derived>();
    }
}

配列の場合は少し異なります。実際には、指定された数のスロットにメモリを予約するようにコンパイラに要求するだけで、そのオブジェクトにメモリを割り当てません (参照型の場合はnull、各スロットに配置するだけです)。

MSDN の参考資料

于 2012-06-04T18:51:12.410 に答える
2

new T()制約を使用してジェネリック型をパラメーターなしのコンストラクターを持つように制約しない限り、言うことはできません—型パラメーターの制約をwhere T : new()参照してください。

また、サポートされているコンストラクターはパラメーターなしのコンストラクターのみであるため、「コンストラクター引数の要件」はありません。たとえば、使用できませんnew T(false)—フォームの制約はwhere T : new(bool)許可されていません。

于 2012-06-04T18:51:40.713 に答える
0

new T()は単なる構文糖衣ですActivator.CreateInstance<T>()

于 2012-06-04T21:17:57.347 に答える