Pouvez-vous m'expliquer ce que where T : class, new()
signifie dans la ligne de code suivante?
void Add<T>(T item) where T : class, new();
C'est une contrainte sur le paramètre générique T
. Il doit s'agir d'un class
(type de référence) et d'un constructeur par défaut sans paramètre public.
Cela signifie que T
ne peut pas être un int
, float
, double
, DateTime
ou tout autre struct
(type de valeur).
Il peut s'agir d'un string
ou de tout autre type de référence personnalisé, à condition qu'il possède un constructeur par défaut ou sans paramètre.
Ce sont des contraintes de type génériques. Dans votre cas, il y en a deux:
where T : class
Signifie que le type T
doit être un type de référence (et non un type de valeur).
where T : new()
Signifie que le type T
doit avoir un constructeur sans paramètre. Avoir cette contrainte vous permettra de faire quelque chose comme T field = new T();
dans votre code, ce que vous ne pourriez faire autrement.
Vous combinez ensuite les deux en utilisant une virgule pour obtenir:
where T : class, new()
où T: struct
L'argument type doit être un type valeur. Tout type de valeur sauf Nullable peut être spécifié. Consultez Utilisation de types nullables (Guide de programmation C #) pour plus d'informations.
où T: classe
L'argument type doit être un type référence, y compris tout type de classe, d'interface, de délégué ou de tableau. (Voir note ci-dessous.)
où T: new () L'argument type doit avoir un constructeur public sans paramètre. Lorsqu'elle est utilisée avec d'autres contraintes, la contrainte new () doit être spécifiée en dernier.
où T: [nom de la classe de base]
L'argument de type doit être ou dériver de la classe de base spécifiée.
où T: [nom de l'interface]
L'argument type doit être ou implémenter l'interface spécifiée. Plusieurs contraintes d'interface peuvent être spécifiées. L'interface contraignante peut aussi être générique.
où T:
L'argument de type fourni pour T doit être dérivé de l'argument fourni pour U. Il s'agit d'une contrainte de type nue.
class
& new
sont 2 contraintes sur le paramètre de type générique T
.
Respectivement, ils assurent:
class
L'argument type doit être un type référence. cela s'applique également à tout type de classe, d'interface, de délégué ou de tableau.
new
L'argument type doit avoir un constructeur public sans paramètre. Lorsqu'elle est utilisée avec d'autres contraintes, la contrainte new () doit être spécifiée en dernier.
Leur combinaison signifie que le type T
doit être un type de référence (ne peut pas être un type de valeur ) et doit avoir un constructeur sans paramètre.
Exemple:
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 (): Spécifier la contrainte new () signifie que le type T doit utiliser un constructeur sans paramètre pour qu'un objet puisse être instancié à partir de celui-ci - voir Constructeurs par défaut
class: Cela signifie que T doit être un type de référence et ne peut donc pas être un int, float, double, DateTime ou autre type de valeur.
public void MakeCars()
{
//This wont compile as researchEngine doesn't have a public constructor and so cant 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();
}
}
Cela signifie que le type T
doit être une classe et avoir un constructeur qui ne prend aucun argument.
Par exemple, vous devez pouvoir faire ceci:
T t = new T();
La contrainte new () indique au compilateur que tout argument de type fourni doit avoir un constructeur accessible sans paramètre - ou default--.
Il devrait en être ainsi, T
doit être une classe et avoir un constructeur accessible sans paramètre - ou par défaut.
Ce qui vient après le "Où" est une contrainte sur le type générique T que vous avez déclaré, donc:
classe signifie que le T devrait être une classe et non un type valeur ou une structure.
new () indique que la classe T doit avoir un constructeur par défaut public sans paramètre défini.
Cela s'appelle une "contrainte" sur le paramètre générique T. Cela signifie que T doit être un type de référence (une classe) et qu'il doit avoir un constructeur public par défaut.
Cela fait partie du mécanisme Generics, où le mot-clé where ajoute des contraintes à ce que les types doivent implémenter pour être utilisés en tant que paramètres de type.