28

簡単な質問:
がある場合string x、それを初期化するには、次のいずれかを実行します。

string x = String.Empty;  

また

string x = null;

ジェネリック パラメータ T はどうですか?

私はやってみました:

void someMethod<T>(T y)
{
    T x = new T();  
    ...
}

生成エラー:
new() 制約がないため、変数型 'T' のインスタンスを作成できません

4

5 に答える 5

42

2つのオプションがあります。

Tを制約できます。これを行うには、メソッドに:where T : new()を追加します。someMethodこれで、パラメーターのないデフォルトのコンストラクターを持つタイプでのみ使用できます(タイプパラメーターの制約を参照)。

または、を使用しますdefault(T)。参照型の場合、これによりnull。ただし、たとえば、整数値の場合、これにより得られます(ジェネリックコードのデフォルトのキーワードを0参照)。

違いを示す基本的なコンソールアプリケーションは次のとおりです。

using System;

namespace Stackoverflow
{
    class Program
    {
        public static T SomeNewMethod<T>()
            where T : new()
        {
            return new T();
        }

        public static T SomeDefaultMethod<T>()
            where T : new()
        {
            return default(T);
        }

        struct MyStruct { }

        class MyClass { }

        static void Main(string[] args)
        {
            RunWithNew();
            RunWithDefault();
        }

        private static void RunWithDefault()
        {
            MyStruct s = SomeDefaultMethod<MyStruct>();
            MyClass c = SomeDefaultMethod<MyClass>();
            int i = SomeDefaultMethod<int>();
            bool b = SomeDefaultMethod<bool>();

            Console.WriteLine("Default");
            Output(s, c, i, b);
        }

        private static void RunWithNew()
        {
            MyStruct s = SomeNewMethod<MyStruct>();
            MyClass c = SomeNewMethod<MyClass>();
            int i = SomeNewMethod<int>();
            bool b = SomeNewMethod<bool>();

            Console.WriteLine("New");
            Output(s, c, i, b);
        }

        private static void Output(MyStruct s, MyClass c, int i, bool b)
        {
            Console.WriteLine("s: " + s);
            Console.WriteLine("c: " + c);
            Console.WriteLine("i: " + i);
            Console.WriteLine("b: " + b);
        }

    }
}

次の出力が生成されます。

New
s: Stackoverflow.Program+MyStruct
c: Stackoverflow.Program+MyClass
i: 0
b: False
Default
s: Stackoverflow.Program+MyStruct
c:
i: 0
b: False
于 2012-12-21T11:16:01.877 に答える
13

defaultキーワードを使用します。

T x = default(T);

参照:ジェネリックコードのデフォルトキーワード(C#プログラミングガイド)

パラメータ化された型Tの変数tが与えられた場合、ステートメントt = nullは、Tが参照型であり、t = 0が数値型に対してのみ機能し、構造体に対しては機能しない場合にのみ有効です。解決策は、デフォルトのキーワードを使用することです。これにより、参照型の場合はnullが返され、数値型の場合は0が返されます。構造体の場合、値型か参照型かに応じて、ゼロまたはnullに初期化された構造体の各メンバーを返します。

于 2012-12-21T11:14:43.670 に答える
9

newtypeパラメータの制約を追加する必要がありますT

void someMethod<T>(T y) where T : new()
{
    T x = new T();  
    ...
}

ただし、これはデフォルトのコンストラクターを持つ型にのみ有効です。

whereTジェネリック型の制約です。この場合、Tこのメソッドが適用されるすべての型には、パブリックパラメーターなしのコンストラクターが必要です。

于 2012-12-21T11:14:56.417 に答える
4

参照型のデフォルトの null 値ではなく、T のインスタンスが本当に必要な場合は、次を使用します。

Activator.CreateInstance()
于 2012-12-21T11:30:47.737 に答える
0

コンストラクトを使用defaultして、そのタイプのデフォルトが何であれ、それを設定できます。

default キーワードを使用すると、コンパイル時にこの変数のデフォルト値を使用する必要があることをコンパイラに伝えることができます。指定された型引数が数値 (int、long、decimal など) の場合、デフォルト値は 0 です。指定された型引数が参照型の場合、既定値は null です。指定された型引数が構造体の場合、構造体のデフォルト値は、構造体の各メンバー フィールドを数値型の場合はゼロに、参照型の場合は null に初期化することによって決定されます。

次のようなものを使用します。

T data = default(T);

詳細については、次を参照してください。ジェネリック変数をデフォルト値に初期化する

于 2012-12-21T11:19:49.880 に答える