Respostas:
Essa é uma restrição no parâmetro genérico T
. Ele deve ser um class
(tipo de referência) e deve ter um construtor padrão sem parâmetro público.
Isso significa que T
não pode ser um int
, float
, double
, DateTime
ou qualquer outro struct
(tipo de valor).
Pode ser um string
ou qualquer outro tipo de referência personalizado, desde que tenha um construtor padrão ou sem parâmetros.
new()
precisamente especifica "deve ter um construtor sem parâmetros público"
Essas são restrições de tipo genérico. No seu caso, existem dois deles:
where T : class
Significa que o tipo T
deve ser um tipo de referência (não um tipo de valor).
where T : new()
Significa que o tipo T
deve ter um construtor sem parâmetros. Ter essa restrição permitirá que você faça algo como T field = new T();
no seu código que você não seria capaz de fazer de outra maneira.
Você então combina os dois usando uma vírgula para obter:
where T : class, new()
onde T: struct
O argumento type deve ser um tipo de valor. Qualquer tipo de valor, exceto Nullable, pode ser especificado. Consulte Usando tipos nulos (Guia de programação em C #) para obter mais informações.
onde T: classe
O argumento type deve ser um tipo de referência, incluindo qualquer classe, interface, delegado ou tipo de matriz. (Ver nota abaixo.)
onde T: new () O argumento type deve ter um construtor público sem parâmetros. Quando usada em conjunto com outras restrições, a nova restrição () deve ser especificada por último.
onde T: [nome da classe base]
O argumento type deve ser ou derivar da classe base especificada.
onde T: [nome da interface]
O argumento type deve ser ou implementar a interface especificada. Múltiplas restrições de interface podem ser especificadas. A interface de restrição também pode ser genérica.
onde T: U
O argumento de tipo fornecido para T deve ser ou derivar do argumento fornecido para U. Isso é chamado de restrição de tipo simples.
class
& new
são 2 restrições no parâmetro de tipo genéricoT
.
Respectivamente, eles garantem:
class
O argumento type deve ser um tipo de referência; isso se aplica também a qualquer classe, interface, delegado ou tipo de matriz.
new
O argumento type deve ter um construtor público sem parâmetros. Quando usada junto com outras restrições, a nova restrição () deve ser especificada por último.
Sua combinação significa que o tipo T
deve ser um Tipo de Referência (não pode ser um Tipo de Valor ) e deve ter um construtor sem parâmetros.
Exemplo:
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 a restrição new () significa que o tipo T deve usar um construtor sem parâmetros, para que um objeto possa ser instanciado a partir dele - consulte Construtores padrão .
classe: significa que T deve ser um tipo de referência para que não possa ser um int, float, double, DateTime ou outra estrutura (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();
}
}
Isso significa que esse tipo T
deve ser uma classe e ter um construtor que não aceita argumentos.
Por exemplo, você deve conseguir fazer isso:
T t = new T();
A nova restrição () permite que o compilador saiba que qualquer argumento de tipo fornecido deve ter um construtor acessível sem parâmetros - ou padrão -
Portanto, deve ser, T
deve ser uma classe e ter um construtor acessível sem parâmetros - ou padrão.
O que vem depois do "Onde" é uma restrição no tipo genérico T que você declarou, portanto:
classe significa que o T deve ser uma classe e não um tipo de valor ou uma estrutura.
new () indica que a classe T deve ter um construtor padrão público sem parâmetros definido.
É chamado de 'restrição' no parâmetro genérico T. Isso significa que T deve ser um tipo de referência (uma classe) e que deve ter um construtor público padrão.
Isso faz parte do mecanismo Genéricos, onde a palavra-chave where adiciona restrições a quais tipos devem ser implementados para serem usados como parâmetros de tipo.