¿Qué significa "donde T: class, new ()"?


¿Puede explicarme qué significa where T : class, new() en la siguiente línea de código?

void Add<T>(T item) where T : class, new();
Author: gonzobrains, 2011-01-19

10 answers

Que es una restricción en el parámetro genérico T. Debe ser un class (tipo de referencia) y debe tener un constructor por defecto sin parámetros públicos.

Eso significa que T no puede ser un int, float, double, DateTime o cualquier otro struct (tipo de valor).

Podría ser un string, o cualquier otro tipo de referencia personalizada, siempre y cuando tenga un constructor predeterminado o sin parámetros.

 254
Author: NerdFury,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-13 21:22:56

Son restricciones de tipo genéricas. En su caso hay dos de ellos:

where T : class

Significa que el tipo T debe ser un tipo de referencia (no un tipo de valor).

where T : new()

Significa que el tipo T debe tener un constructor sin parámetros. Tener esta restricción le permitirá hacer algo como T field = new T(); en su código que no podría hacer de otra manera.

Luego combinas los dos usando una coma para obtener:

where T : class, new()
 125
Author: Justin Niessner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-19 16:45:02

Donde T: struct

El argumento type debe ser un tipo value. Se puede especificar cualquier tipo de valor excepto Nullable. Consulte Uso de tipos Nullables (Guía de Programación en C#) para obtener más información.

Donde T: clase

El argumento type debe ser un tipo de referencia, incluyendo cualquier clase, interfaz, delegado o tipo array. (Véase la nota infra.)

Donde T: new () El argumento type debe tener un constructor público sin parámetros. Cuando se utiliza conjuntamente con otras restricciones, la restricción new() debe especificarse en último lugar.

Donde T: [nombre de la clase base]

El argumento type debe ser o derivar de la clase base especificada.

Donde T: [nombre de la interfaz]

El argumento type debe ser o implementar la interfaz especificada. Se pueden especificar múltiples restricciones de interfaz. La interfaz restrictiva también puede ser genérica.

Donde T: U

El argumento de tipo suministrado para T debe ser o derivar del argumento suministrado para U. Esto se llama una restricción de tipo naked.

 94
Author: Mohammed Jubayer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-20 05:32:24

New (): Especificar la restricción new () significa que el tipo T debe usar un constructor sin parámetros, por lo que un objeto puede ser instanciado desde él-ver Constructores predeterminados

Class: Significa que T debe ser un tipo de referencia para que no pueda ser un int, float, double, DateTime u otra estructura (tipo de valor).

    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();
        }
    }
 12
Author: Brendan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-20 11:38:48

class & new son 2 restricciones en el parámetro de tipo genérico T.
Respectivamente, aseguran:

class

El argumento type debe ser un tipo de referencia; esto se aplica también a cualquier tipo de clase, interfaz, delegado o matriz.

new

El argumento type debe tener un constructor público sin parámetros. Cuando se usa junto con otras restricciones, la restricción new() debe especificarse en último lugar.

Su combinación significa que el tipo T debe ser un Tipo de referencia (no puede ser un Tipo de valor ), y debe tener un constructor sin parámetros.

Ejemplo:

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
}
 9
Author: Sergio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-26 03:08:25

Eso significa que el tipo T debe ser una clase y tener un constructor que no tome ningún argumento.

Por ejemplo, usted debe ser capaz de hacer esto:

T t = new T();
 6
Author: Evan Mulawski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-19 16:39:55

Donde (Referencia C#)

La restricción new() le permite al compilador saber que cualquier argumento de tipo suministrado debe tener un constructor accesible sin parámetros {o por defecto {

Así que debería ser, T debe ser una clase, y tener un constructor accesible sin parámetros accessible o predeterminado.

 4
Author: Fredrik Widerberg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-24 09:21:09

Lo que viene después del "Dónde" es una restricción en el tipo genérico T que declaró, así que:

  • Class significa que la T debe ser una clase y no un tipo de valor o una estructura.

  • New () indica que la clase T debe tener definido un constructor por defecto libre de parámetros públicos.

 3
Author: Otman IGHOULASSEN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-11 17:15:34

Se llama una 'restricción' en el parámetro genérico T. Significa que T debe ser un tipo de referencia (una clase) y que debe tener un constructor público predeterminado.

 1
Author: Josh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-19 16:41:08

Esto es parte del mecanismo Genérico, donde la palabra clave where agrega restricciones a qué tipos deben implementarse para ser utilizados como parámetros de tipo.

 1
Author: Peter Lillevold,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-19 16:41:08