Resumo : neste tutorial, você aprenderá sobre restrições genéricas do C# que permitem especificar quais tipos de tipos são aceitáveis como argumentos.
Introdução às restrições genéricas do C#
O exemplo a seguir define uma classe genérica Result<T>
:
class Result<T>
{
T Data { get; set; }
int Status { get; set; }
public Result(T data, int status)
{
Data = data;
Status = status;
}
}
Linguagem de código: C# ( cs )
Neste exemplo, o único argumento Result<T>
atribui ao membro. Ele não faz mais nada que exija operações do tipo .data
Data
T
A razão é que ele Result<T>
não conhece os dados do tipo T
que irá armazenar. Portanto, não é possível conhecer os membros do tipo T
.
Como todos os objetos são derivados da object
classe, incluindo T
, a Result<T>
classe conhece apenas os membros da object
classe, como ToString()
,, Equals()
e GetType()
.
Contanto que a Result<T>
classe não acesse o membro do tipo T
diferente dos membros da object
classe, a Result<T>
classe pode manipular qualquer tipo. Este parâmetro de tipo é chamado de parâmetro de tipo ilimitado .
Entretanto, se você tentar usar qualquer outro membro, o compilador produzirá uma mensagem de erro. Por exemplo:
class Result<T>
{
T Data { get; set; }
int Status { get; set; }
public Result(T data, int status)
{
Data = data;
Status = status;
}
public string JSON()
{
return Data?.ToJSON(); // ERROR
}
}
Linguagem de código: C# ( cs )
Este exemplo causa um erro porque o JSON()
método da Result<T>
classe tenta chamar o ToJSON()
método do Data
membro.
Para tornar a Result<T>
classe mais útil, você pode especificar as informações sobre os tipos de tipos que são aceitáveis como argumentos. Essas informações adicionais são chamadas de restrições genéricas .
Para especificar uma restrição genérica, você usa a where
cláusula após o colchete angular de fechamento da lista de parâmetros de tipo:
class MyClass<T> where TypeParam: constraint, constraint,
Linguagem de código: C# ( cs )
Por exemplo, o seguinte especifica que o tipo T deve ser um tipo que implemente a IJSON
interface:
interface IJSON
{
string ToJSON();
}
class Result<T>
where T : IJSON
{
T Data { get; set; }
int Status { get; set; }
public Result(T data, int status)
{
Data = data;
Status = status;
}
public string JSON()
{
return Data?.ToJSON();
}
}
Linguagem de código: C# ( cs )
Tipos e ordem de restrições genéricas em C#
C# fornece cinco tipos de restrições genéricas:
Tipo de restrição | Descrição |
---|---|
Nome da classe | O argumento de tipo é a classe deste tipo ou classes derivadas dele. |
aula | O argumento de tipo pode ser qualquer tipo de referência, incluindo classes, arrays, delegados e interfaces. |
estrutura | O argumento de tipo pode ser qualquer tipo de valor |
NomedaInterface | O argumento de tipo pode ser a interface ou tipos que implementam esta interface |
novo() | O argumento de tipo com o construtor público sem parâmetros. |
Um tipo genérico pode ter múltiplas restrições. Em outras palavras, pode ter várias where
cláusulas como esta:
class MyClass<T1, T2, T3>
where T2: MyClass2
where T3: IMyInterface
{
//...
}
Linguagem de código: C# ( cs )
A ordem das where
cláusulas não é importante. No entanto, as restrições em uma where
cláusula são importantes. O seguinte mostra a ordem das restrições:
Primário (0 ou 1) | Secundário (0 ou mais) | Construtor (0 ou 1) |
---|---|---|
Estrutura da classe ClassName |
NomedaInterface | novo() |
Resumo
- As restrições genéricas especificam restrições no tipo usado como argumentos para parâmetros de tipo em tipo genérico.
- Use as
where
cláusulas para especificar restrições genéricas.