Respuestas:
Esa es una restricción en el parámetro genérico T
. Debe ser un class
(tipo de referencia) y debe tener un constructor público predeterminado sin parámetros.
Eso significa que T
no pueden ser una int
, float
, double
, DateTime
o cualquier otro struct
(tipo de valor).
Podría ser un string
, o cualquier otro tipo de referencia personalizado, siempre que tenga un constructor predeterminado o sin parámetros.
new()
especifica con precisión "debe tener un constructor público sin parámetros"
Esas son restricciones de tipo genérico. 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 de otra manera no podría hacer.
Luego combina los dos usando una coma para obtener:
where T : class, new()
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, que incluye cualquier clase, interfaz, delegado o tipo de matriz. (Vea la nota abajo.)
donde T: 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.
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 proporcionado para T debe ser o derivar del argumento proporcionado para U. Esto se denomina restricción de tipo simple.
class
& new
son 2 restricciones en el parámetro de tipo genéricoT
.
Respectivamente aseguran:
class
El argumento tipo debe ser un tipo de referencia; Esto se aplica también a cualquier clase, interfaz, delegado o tipo de matriz.
new
El argumento 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.
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
}
new (): especificar la restricción new () significa que el tipo T debe usar un constructor sin parámetros, por lo que se puede crear una instancia de un objeto a partir de él; consulte Constructores predeterminados .
clase: significa que T debe ser un tipo de referencia, por lo que no puede ser int, float, double, DateTime u otra estructura (tipo de valor).
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();
}
}
Eso significa que el tipo T
debe ser una clase y tener un constructor que no tome ningún argumento.
Por ejemplo, debe poder hacer esto:
T t = new T();
La nueva restricción () le permite al compilador saber que cualquier argumento de tipo proporcionado debe tener un constructor accesible sin parámetros o predeterminado
Por lo tanto, debe ser, T
debe ser una clase y tener un constructor accesible sin parámetros o predeterminado.
Lo que viene después del "Dónde" es una restricción sobre el tipo genérico T que declaró, así 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 público predeterminado sin parámetros definido.
Se llama '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.
Esto es parte del mecanismo genérico, donde la palabra clave where agrega restricciones a los tipos que deben implementarse para ser utilizados como parámetros de tipo.