Контравариантность in
Ключевое слово in ставят у параметра типа,
если T используется только во входящих
аргументах (параметры методов). Тогда
IWrite<Animal> можно присвоить
переменной IWrite<Cat>: обработчик,
умеющий записать любое Animal, подходит
и для Cat. Это противоположно
out.
Синтаксис
interface IWrite<in T>
{
void Write(T value);
}
IWrite<Производный> slot = new Реализация<Базовый>();
Пример
Давайте присвоим IWrite<Animal> переменной
IWrite<Cat> и запишем имя:
using System;
interface IWrite<in T>
{
void Write(T value);
}
class Animal
{
public string Name = "animal";
}
class Cat : Animal { }
class Log : IWrite<Animal>
{
public void Write(Animal value)
{
Console.WriteLine(value.Name);
}
}
class Program
{
static void Main()
{
IWrite<Cat> slot = new Log();
slot.Write(new Cat { Name = "abcde" });
}
}
Результат выполнения кода:
"abcde"
Пример
Давайте передадим контравариантный слот в
метод, который принимает IWrite<Cat>:
using System;
interface IWrite<in T>
{
void Write(T value);
}
class Animal
{
public string Name;
}
class Cat : Animal { }
class Log : IWrite<Animal>
{
public void Write(Animal value)
{
Console.WriteLine(value.Name);
}
}
class Program
{
static void Use(IWrite<Cat> slot, Cat cat)
{
slot.Write(cat);
}
static void Main()
{
IWrite<Cat> slot = new Log();
Use(slot, new Cat { Name = "12345" });
}
}
Результат выполнения кода:
"12345"
Пример
Давайте сохраним более широкий обработчик в массиве узких слотов:
using System;
interface IWrite<in T>
{
void Write(T value);
}
class Animal
{
public string Name;
}
class Cat : Animal { }
class Log : IWrite<Animal>
{
public void Write(Animal value)
{
Console.WriteLine(value.Name);
}
}
class Program
{
static void Main()
{
IWrite<Cat>[] slots = { new Log(), new Log() };
slots[0].Write(new Cat { Name = "abcde" });
}
}
Результат выполнения кода:
"abcde"
Смотрите также
-
ковариантность
out,
которая расширяет тип в результате -
наследование
inheritance,
которое связываетCatиAnimal -
интерфейс
interface,
где объявляютIWrite<in T> -
класс
List,
чейTпо умолчанию инвариантен