Antworten:
Dies ist eine Einschränkung für den generischen Parameter T
. Es muss ein class
(Referenztyp) sein und einen öffentlichen parameterlosen Standardkonstruktor haben.
Das bedeutet T
nicht sein kann int
, float
, double
, DateTime
oder jede andere struct
(value - Typ).
Es kann sich um einen string
oder einen anderen benutzerdefinierten Referenztyp handeln, sofern er einen Standardkonstruktor oder einen parameterlosen Konstruktor hat.
new()
spezifiziert genau "muss einen öffentlichen parameterlosen Konstruktor haben"
Dies sind generische Typeinschränkungen. In Ihrem Fall gibt es zwei davon:
where T : class
Bedeutet, dass der Typ T
ein Referenztyp sein muss (kein Werttyp).
where T : new()
Bedeutet, dass der Typ T
einen parameterlosen Konstruktor haben muss. Mit dieser Einschränkung können Sie so etwas wie T field = new T();
in Ihrem Code tun, was Sie sonst nicht tun könnten.
Sie kombinieren die beiden dann mit einem Komma, um Folgendes zu erhalten:
where T : class, new()
wo T: struct
Das Typargument muss ein Werttyp sein. Jeder Werttyp außer Nullable kann angegeben werden. Weitere Informationen finden Sie unter Verwenden nullbarer Typen (C # -Programmierhandbuch).
wo T: Klasse
Das Typargument muss ein Referenztyp sein, einschließlich aller Klassen-, Schnittstellen-, Delegaten- oder Arraytypen. (Siehe Anmerkung unten.)
Dabei ist T: new () Das Argument type muss einen öffentlichen parameterlosen Konstruktor haben. In Verbindung mit anderen Einschränkungen muss die neue () Einschränkung zuletzt angegeben werden.
wobei T: [Name der Basisklasse]
Das Typargument muss von der angegebenen Basisklasse sein oder von dieser abgeleitet sein.
wo T: [Schnittstellenname]
Das Typargument muss die angegebene Schnittstelle sein oder diese implementieren. Es können mehrere Schnittstellenbeschränkungen angegeben werden. Die einschränkende Schnittstelle kann auch generisch sein.
wo T: U.
Das für T angegebene Typargument muss das für U angegebene Argument sein oder von diesem abgeleitet sein. Dies wird als nackte Typbeschränkung bezeichnet.
class
& new
sind zwei Einschränkungen für den generischen TypparameterT
.
Sie stellen jeweils sicher:
class
Das Typargument muss ein Referenztyp sein. Dies gilt auch für alle Klassen, Schnittstellen, Delegaten oder Array-Typen.
new
Das Typargument muss einen öffentlichen parameterlosen Konstruktor haben. Bei Verwendung zusammen mit anderen Einschränkungen muss die neue () Einschränkung zuletzt angegeben werden.
Ihre Kombination bedeutet, dass der Typ T
ein Referenztyp sein muss (kann kein Werttyp sein ) und einen parameterlosen Konstruktor haben muss.
Beispiel:
struct MyStruct { } // structs are value types
class MyClass1 { } // no constructors defined, so the class implicitly has a parameterless one
class MyClass2 // parameterless constructor explicitly defined
{
public MyClass2() { }
}
class MyClass3 // only non-parameterless constructor defined
{
public MyClass3(object parameter) { }
}
class MyClass4 // both parameterless & non-parameterless constructors defined
{
public MyClass4() { }
public MyClass4(object parameter) { }
}
interface INewable<T>
where T : new()
{
}
interface INewableReference<T>
where T : class, new()
{
}
class Checks
{
INewable<int> cn1; // ALLOWED: has parameterless ctor
INewable<string> n2; // NOT ALLOWED: no parameterless ctor
INewable<MyStruct> n3; // ALLOWED: has parameterless ctor
INewable<MyClass1> n4; // ALLOWED: has parameterless ctor
INewable<MyClass2> n5; // ALLOWED: has parameterless ctor
INewable<MyClass3> n6; // NOT ALLOWED: no parameterless ctor
INewable<MyClass4> n7; // ALLOWED: has parameterless ctor
INewableReference<int> nr1; // NOT ALLOWED: not a reference type
INewableReference<string> nr2; // NOT ALLOWED: no parameterless ctor
INewableReference<MyStruct> nr3; // NOT ALLOWED: not a reference type
INewableReference<MyClass1> nr4; // ALLOWED: has parameterless ctor
INewableReference<MyClass2> nr5; // ALLOWED: has parameterless ctor
INewableReference<MyClass3> nr6; // NOT ALLOWED: no parameterless ctor
INewableReference<MyClass4> nr7; // ALLOWED: has parameterless ctor
}
new (): Wenn Sie die Einschränkung new () angeben, muss Typ T einen parameterlosen Konstruktor verwenden, damit ein Objekt daraus instanziiert werden kann - siehe Standardkonstruktoren .
Klasse: Bedeutet, dass T ein Referenztyp sein muss, damit es sich nicht um eine int-, float-, double-, DateTime- oder andere Struktur (Werttyp) handeln kann.
public void MakeCars()
{
//This won't compile as researchEngine doesn't have a public constructor and so can't be instantiated.
CarFactory<ResearchEngine> researchLine = new CarFactory<ResearchEngine>();
var researchEngine = researchLine.MakeEngine();
//Can instantiate new object of class with default public constructor
CarFactory<ProductionEngine> productionLine = new CarFactory<ProductionEngine>();
var productionEngine = productionLine.MakeEngine();
}
public class ProductionEngine { }
public class ResearchEngine
{
private ResearchEngine() { }
}
public class CarFactory<TEngine> where TEngine : class, new()
{
public TEngine MakeEngine()
{
return new TEngine();
}
}
Das bedeutet, dass type T
eine Klasse sein und einen Konstruktor haben muss, der keine Argumente akzeptiert.
Zum Beispiel müssen Sie dazu in der Lage sein:
T t = new T();
Die new () - Einschränkung informiert den Compiler darüber, dass jedes angegebene Typargument einen zugänglichen parameterlosen oder standardmäßigen Konstruktor haben muss
So sollte es sein, T
muss eine Klasse sein und einen zugänglichen parameterlosen - oder Standardkonstruktor haben.
Was nach dem "Wo" kommt, ist eine Einschränkung für den von Ihnen deklarierten generischen Typ T, also:
Klasse bedeutet, dass das T eine Klasse und kein Werttyp oder eine Struktur sein sollte.
new () gibt an, dass für die T-Klasse ein öffentlicher parameterfreier Standardkonstruktor definiert sein sollte.
Es wird als 'Einschränkung' für den generischen Parameter T bezeichnet. Dies bedeutet, dass T ein Referenztyp (eine Klasse) sein und einen öffentlichen Standardkonstruktor haben muss.
Dies ist Teil des Generics-Mechanismus, bei dem das Schlüsselwort where Einschränkungen hinzufügt, welche Typen implementiert werden müssen, um als Typparameter verwendet zu werden.
Wenn Sie die Klasse in Einschränkungen verwenden, bedeutet dies, dass Sie nur den Referenztyp verwenden können. Eine weitere Sache, die Sie hinzufügen müssen, ist, wann Sie die Einschränkung new () verwenden müssen. Dies muss das letzte sein, was Sie in die Constraints-Begriffe schreiben.