web-dev-qa-db-fra.com

Que signifie "où T: classe, new ()" signifie?

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();
267
Rawhi

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.

294
NerdFury

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()
147
Justin Niessner

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.

109
Mohammed Jubayer

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
}
17
Sergio

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();
        }
    }
14
Brendan

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();
6
Evan Mulawski

où (référence C #)

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.

5
Fredrik Widerberg

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.

3
Otman IGHOULASSEN

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.

1
Josh

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.

1
Peter Lillevold