402 Stimmen

Was bedeutet "where T : class, new()"?

Können Sie mir bitte erklären, was where T : class, new() in der folgenden Codezeile bedeutet?

void Add(T item) where T : class, new();

13 Stimmen

0 Stimmen

Ist deine Frage damit beantwortet? Was bedeutet new()?

434voto

NerdFury Punkte 18121

Dies ist eine Einschränkung für den generischen Parameter T. Es muss eine Klasse (Referenztyp) sein und einen öffentlichen parameterlosen Standardkonstruktor haben.

Das bedeutet, dass T kein int, float, double, DateTime oder eine andere strukt (Werttyp) sein kann.

Es könnte ein string sein oder ein anderer benutzerdefinierter Referenztyp, solange er einen Standard- oder parameterlosen Konstruktor hat.

6 Stimmen

Nur zur Klarstellung, wenn Sie den Klassenklausel nicht als Teil des where T... haben, ist es sicher, int, float, double etc. zu verwenden.

1 Stimmen

@ AboutDev korrekt, Sie müssen keine Beschränkungen für Ihren generischen Typ-Parameter festlegen. Aber wenn Sie einen generischen Typ erstellen, der nur mit Referenz- oder Werttypen arbeiten soll, sollten Sie dies angeben. Ohne Einschränkung können Sie Referenztypen (Klassen) oder Werttypen (Strukturen (int, float, double...)) erwarten.

1 Stimmen

Was ist mit T : [Schnittstellenname], new() ? Brauchen Sie immer noch einen parameterlosen Konstruktor?

224voto

Justin Niessner Punkte 235353

Dies sind allgemeine Typbeschränkungen. In Ihrem Fall gibt es zwei davon:

where T : class

Bedeutet, dass der Typ T ein Verweistyp sein muss (kein Werttyp).

where T : new()

Bedeutet, dass der Typ T einen parameterlosen Konstruktor haben muss. Wenn diese Beschränkung vorhanden ist, können Sie etwas wie T field = new T(); in Ihrem Code tun, was Sie sonst nicht tun könnten.

Sie kombinieren dann beide durch ein Komma, um zu erhalten:

where T : class, new()

0 Stimmen

Gute Punkte für den zweiten und dritten, nur um Informationen hinzuzufügen, ich denke, der zweite Punkt ist nützlich, wenn man Reflexion im generischen Typ macht. z. B. T t = new T(); t.GetType().GetProperty("ID").SetValue(t, uniqueId, null);

1 Stimmen

Ich glaube, es ist überflüssig zu sagen, wo T : class, new(), da new() bereits Klasse impliziert, weil Strukturen keine Standardkonstruktoren haben können.

1 Stimmen

@DharmaTurtle, "Strukturen können keinen expliziten parameterlosen Konstruktor enthalten", bedeutet nicht, dass sie keinen haben, sondern besagt, dass man keinen definieren kann. Quelle: msdn.microsoft.com/tr-tr/library/aa288208(v=vs.71).aspx

162voto

Mohammed Jubayer Punkte 1564

wo T : struct

Das Typargument muss ein Werttyp sein. Es kann jeder Werttyp außer Nullable angegeben werden. Weitere Informationen finden Sie unter Verwenden von Nullable-Typen (C#-Programmierhandbuch).

wo T : class

Das Typargument muss ein Verweistyp sein, einschließlich jeder Klasse, jedes Interfaces, Delegaten oder Arraytyps. (Siehe Anmerkung unten.)

wo T : new() Das Typargument muss einen öffentlichen parameterlosen Konstruktor haben. Bei Verwendung in Verbindung mit anderen Beschränkungen muss die new()-Beschränkung als letzte angegeben werden.

wo T : [Basisklassenname]

Das Typargument muss von der angegebenen Basisklasse sein oder von ihr abgeleitet sein.

wo T : [Interfacename]

Das Typargument muss das angegebene Interface sein oder implementieren. Mehrere Interface-Beschränkungen können angegeben werden. Das eingeschränkte Interface kann auch generisch sein.

wo T : U

Das für T bereitgestellte Typargument muss vom für U bereitgestellten Argument sein oder von diesem abgeleitet sein. Dies wird als nackter Typbeschränkung bezeichnet.

(Ursprüngliche Quelle: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters)

28 Stimmen

Dies war nützlich, aber Link zur Quelle.

37voto

Sergio Punkte 1980

class & new sind 2 Einschränkungen für den generischen Typparameter T.
Sie stellen sicher:

class

Das Typargument muss ein Verweistyp sein; dies gilt auch für jeden Klassentyp, Schnittstellentyp, Delegattyp oder Arraytyp.

new

Das Typargument muss über einen öffentlichen parameterlosen Konstruktor verfügen. Wenn zusammen mit anderen Einschränkungen verwendet, muss die new() Einschränkung zuletzt angegeben werden.

Durch ihre Kombination bedeutet dies, dass der Typ T ein Verweistyp sein muss (kann kein Werttyp sein) und über einen parameterlosen Konstruktor verfügen muss.

Beispiel:

struct MyStruct { } // Strukturen sind Werttypen

class MyClass1 { } // keine Konstruktoren definiert, daher hat die Klasse implizit einen parameterlosen Konstruktor

class MyClass2 // parameterloser Konstruktor explizit definiert
{
    public MyClass2() { }
}

class MyClass3 // nur nicht-parameterloser Konstruktor definiert
{
    public MyClass3(object parameter) { }
}

class MyClass4 // sowohl parameterlose als auch nicht-parameterlose Konstruktoren definiert
{
    public MyClass4() { }
    public MyClass4(object parameter) { }
}

interface INewable
    where T : new()
{
}

interface INewableReference
    where T : class, new()
{
}

class Checks
{
    INewable cn1; // ERLAUBT: hat parameterlosen Konstruktor
    INewable n2; // NICHT ERLAUBT: kein parameterloser Konstruktor
    INewable n3; // ERLAUBT: hat parameterlosen Konstruktor
    INewable n4; // ERLAUBT: hat parameterlosen Konstruktor
    INewable n5; // ERLAUBT: hat parameterlosen Konstruktor
    INewable n6; // NICHT ERLAUBT: kein parameterloser Konstruktor
    INewable n7; // ERLAUBT: hat parameterlosen Konstruktor

    INewableReference nr1; // NICHT ERLAUBT: kein Verweistyp
    INewableReference nr2; // NICHT ERLAUBT: kein parameterloser Konstruktor
    INewableReference nr3; // NICHT ERLAUBT: kein Verweistyp
    INewableReference nr4; // ERLAUBT: hat parameterlosen Konstruktor
    INewableReference nr5; // ERLAUBT: hat parameterlosen Konstruktor
    INewableReference nr6; // NICHT ERLAUBT: kein parameterloser Konstruktor
    INewableReference nr7; // ERLAUBT: hat parameterlosen Konstruktor
}

1 Stimmen

Gute Demonstration. Danke.

17voto

Brendan Punkte 1446

new(): Die Angabe der new() -Einschränkung bedeutet, dass der Typ T einen parameterlosen Konstruktor verwenden muss, damit ein Objekt daraus instanziiert werden kann - siehe Standardkonstruktoren.

Klasse: Bedeutet, dass T ein Verweistyp sein muss, damit es kein int, float, double, DateTime oder ein anderer Strukturtyp (Werttyp) sein kann.

public void MakeCars()
{
    //Dies wird nicht kompilieren, da researchEngine keinen öffentlichen Konstruktor hat und daher nicht instanziiert werden kann.
    CarFactory researchLine = new CarFactory();
    var researchEngine = researchLine.MakeEngine();

    //Kann neues Objekt der Klasse mit Standardkonstruktor instanziieren
    CarFactory productionLine = new CarFactory();
    var productionEngine = productionLine.MakeEngine();
}

public class ProductionEngine { }
public class ResearchEngine
{
    private ResearchEngine() { }
}

public class CarFactory where TEngine : class, new()
{
    public TEngine MakeEngine()
    {
        return new TEngine();
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X