Resumo : neste tutorial, você aprenderá sobre a contravariância do C# e como usá-la para tornar seu código mais flexível.
Introdução à Contravariância C#
Contravariância é um mecanismo em C# que permite que um método aceite um parâmetro de um tipo menos específico do que o definido na assinatura do método.
Em outras palavras, a contravariância permite que um método aceite um argumento de uma classe base ou tipo de interface , mesmo que o tipo de parâmetro seja uma classe derivada ou um tipo de interface. C# usa a in
palavra-chave para definir uma interface como uma contravariância.
Por exemplo, você pode definir uma interface genérica como uma contravariância como esta:
interface MyInterface<in T>
{
void MyMethod(T item);
}
Linguagem de código: C# ( cs )
A in
palavra-chave significa que você pode usar the T
como o tipo de parâmetros dos métodos. Se você tentar retornar um valor do tipo T
, receberá um erro. Por exemplo:
interface MyInterface<in T>
{
void MyMethod(T item);
T ReturnItem(); // ERROR
}
Linguagem de código: C# ( cs )
Observe que para definir T
como o tipo de valor de retorno, você usa a covariância .
Exemplo de contravariância em C#
O exemplo a seguir demonstra como funciona a contravariância.
using static System.Console;
class Person
{
public string Name
{
get; set;
}
public Person(string name)
{
Name = name;
}
}
class Employee : Person
{
public string JobTitle
{
get; set;
}
public Employee(string name, string jobTitle) : base(name)
{
JobTitle = jobTitle;
}
}
interface IGroup<in T>
{
void Add(T item);
int Count
{
get;
}
}
class Group<T> : IGroup<T>
{
private readonly List<T> list = new();
public int Count => list.Count;
public void Add(T item) => list.Add(item);
}
class Program
{
public static void Display(IGroup<Employee> group)
{
WriteLine(group.Count);
}
public static void Main(string[] args)
{
IGroup<Person> group = new Group<Person>();
group.Add(new Person("John Doe"));
group.Add(new Person("Jane Doe"));
Display(group);
}
}
Linguagem de código: C# ( cs )
Saída:
2
Como funciona.
Primeiro, defina a Person
classe que possui a Name
propriedade e a Employee
classe que herda da Person
classe. A Employee
classe possui JobTitle
propriedades adicionais.
A seguir, defina a IGroup<T>
interface como contravariância usando a palavra-chave in
. O IGroup<T>
tem um método Add()
e uma Count
propriedade.
Em seguida, defina a Group<T>
classe que implementa a IGroup<T>
interface. O Add()
método adiciona um item com tipo T
a uma lista e a Count
propriedade retorna o número de itens na lista.
Depois disso, defina o Display
método que aceita uma instância IGroup<Employee>
e mostra a quantidade de itens do grupo para o console.
Por fim, crie um grupo de Person
objetos e passe-o para o Display
método. Como IGroup<T>
é uma contravariância, o programa foi executado com sucesso.
Mas se você retirar a in
palavra-chave da IGroup<T>
interface, o programa não será compilado.
Resumo
- Em C#, contravariância é um recurso que permite que um método receba um argumento menos específico do que aquele definido na assinatura do método.
- Use a palavra-chave
in
para definir uma interface como uma contravariância.