wake-up-neo.com

Wie wird der generische Parametertyp T initialisiert?

Einfache Frage:
Wenn Sie über einen string x verfügen, führen Sie zur Initialisierung einfach einen der folgenden Schritte aus: 

string x = String.Empty;  

oder 

string x = null;

Was ist mit dem generischen Parameter T? 

Ich habe es versucht: 

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

Fehler erzeugen:
Eine Instanz des Variablentyps 'T' kann nicht erstellt werden, da sie nicht die new () - Einschränkung hat

19
JavaSa

Sie haben zwei Möglichkeiten:

Sie können T: einschränken, indem Sie Ihrer Methode Folgendes hinzufügen: where T : new(). Jetzt können Sie die someMethod nur mit einem Typ verwenden, der über einen parameterlosen Standardkonstruktor verfügt (siehe Einschränkungen für Typparameter ).

Oder Sie verwenden default(T). Für einen Referenztyp ergibt dies null. Bei einem ganzzahligen Wert ergibt dies beispielsweise 0 (siehe Standardschlüsselwort in Generic Code ).

Hier ist eine grundlegende Konsolenanwendung, die den Unterschied demonstriert:

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);
        }

    }
}

Es erzeugt die folgende Ausgabe:

New
s: Stackoverflow.Program+MyStruct
c: Stackoverflow.Program+MyClass
i: 0
b: False
Default
s: Stackoverflow.Program+MyStruct
c:
i: 0
b: False
30
Wouter de Kort

verwenden Sie das default-Schlüsselwort. 

T x = default(T);

Siehe: Standardschlüsselwort in generischem Code (C # -Programmierhandbuch)

Bei einer Variablen t eines parametrisierten Typs T ist die Anweisung t = null ist nur gültig, wenn T ein Referenztyp ist und t = 0 nur für .__ funktioniert. numerische Werttypen, jedoch nicht für Strukturen. Die Lösung ist die Verwendung der Standardschlüsselwort, das für Referenztypen Null und Null zurückgibt für numerische Werttypen. Bei Strukturen wird jedes Mitglied von .__ zurückgegeben. Die Struktur wird auf null oder null initialisiert, abhängig davon, ob sie .__ sind. Wert oder Referenztypen.

9
Habib

Sie müssen eine new-Einschränkung für den Typparameter T hinzufügen.

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

Dies gilt jedoch nur für Typen mit einem Standardkonstruktor.

Die where-Klausel für T ist eine generische Typeinschränkung . In diesem Fall muss jeder Typ T, auf den diese Methode angewendet wird, über einen öffentlichen parameterlosen Konstruktor verfügen.

7
Lee

Wenn Sie wirklich eine Instanz von T und keinen Standardwert für Referenztypen benötigen, verwenden Sie Folgendes:

Activator.CreateInstance()
4
Oscar

Sie können das default -Konstrukt verwenden, um es auf die Standardeinstellung dieses Typs festzulegen.

Mit dem Standardschlüsselwort können Sie dem Compiler mitteilen, dass zum Zeitpunkt der Kompilierung der Standardwert dieser Variablen verwendet werden soll. Wenn das angegebene Typargument ein numerischer Wert ist (z. B. int, long, decimal), ist der Standardwert Null. Wenn das angegebene Typargument ein Referenztyp ist, ist der Standardwert null. Wenn das angegebene Typargument eine Struktur ist, wird der Standardwert der Struktur bestimmt, indem jedes Elementfeld der Struktur für numerische Typen mit Null oder für Referenztypen mit Null initialisiert wird.

Verwenden Sie etwas wie:

T data = default(T);

Weitere Informationen finden Sie unter: Initialisieren generischer Variablen auf ihre Standardwerte

0
Amar