variable multiple method interfaces generic example create clase c# generics type-constraints

multiple - interface where t class c#



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

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

void Add<T>(T item) where T : class, new();


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

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

Puede ser una string o cualquier otro tipo de referencia personalizado, siempre que tenga un constructor predeterminado o sin parámetros.


Esas son restricciones de tipo genérico. En tu 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 te permitirá hacer algo como el T field = new T(); en su código que no podría hacer de otra manera.

Luego combina los dos usando una coma para obtener:

where T : class, new()


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

Por ejemplo, debe ser capaz de hacer esto:

T t = new T();


Esto es parte del mecanismo de Genéricos, donde la palabra clave donde se agregan restricciones a los tipos que deben implementarse para que se utilicen como parámetros de tipo.


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

  • clase 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 un constructor predeterminado público libre de parámetros definido.


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


donde (Referencia C #)

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

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


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

class

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

new

El argumento de tipo debe tener un constructor público sin parámetros. Cuando se usa junto con otras restricciones, la nueva restricción () 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 }


donde T: struct

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

donde T: clase

El argumento de tipo debe ser un tipo de referencia, incluida cualquier clase, interfaz, delegado o tipo de matriz. (Vea la nota abajo.)

donde T: new () El argumento de tipo 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.

donde T: [nombre de la clase base]

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

donde T: [nombre de la interfaz]

El argumento de tipo debe ser o implementar la interfaz especificada. Se pueden especificar múltiples restricciones de interfaz. La interfaz de restricción 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 denomina una restricción de tipo simple.


new (): especificar la nueva () restricción significa que el tipo T debe usar un constructor sin parámetros, de modo que se pueda crear una instancia de un objeto desde él. Consulte Constructores predeterminados.

clase: 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(); } }