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();
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();
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.
Nur zur Klarstellung, wenn Sie den Klassenklausel nicht als Teil des where T... haben, ist es sicher, int, float, double etc. zu verwenden.
@ 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.
Was ist mit T : [Schnittstellenname], new() ? Brauchen Sie immer noch einen parameterlosen Konstruktor?
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()
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);
Ich glaube, es ist überflüssig zu sagen, wo T : class, new(), da new() bereits Klasse impliziert, weil Strukturen keine Standardkonstruktoren haben können.
@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
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)
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
}
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 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.
13 Stimmen
Für spätere Verwendung: msdn.microsoft.com/en-us/library/d5x73970.aspx
0 Stimmen
Ist deine Frage damit beantwortet? Was bedeutet new()?