- PVSM.RU - https://www.pvsm.ru -

Определение вариантности в C#

Зачем

О вариантности в C# написано множество хороших статей. Но читая о её проявлениях в разных аспектах языка я столкнулся с тем, что каждый раз её представляют мне несколько иначе, чем в прошлый раз. Поэтому мне не удавалось сформулировать чёткое определение — шаблон, который хорошо соответствовал бы каждому проявлению вариантности, с которым я сталкиваюсь, и позволил бы мне держать в голове лишь одну концепцию, вместо набора различных ситуаций. Эта заметка — моя попытка сформулировать нужный шаблон.

Определение

Вариантность — это свойство преобразования типов операторами.

Оператор — любая сущность языка C#, преобразующая типы данных в производные от них. Например, оператором явялется T[] создающий производный тип массива из типа T, Action<T> создающий производный тип действия с одним параметром из T. Оператор группы методов T MyMethod(U), преобразует сразу два типа: T, создавая производный тип возвращаемое значение и U, создавая производный тип аргумент метода. Те же преобразования осуществляет и оператор создания типа делегата Func<U,T>. Но в последнем случае эти преобразования отличаются от первого своими своиствами — вариантностью.

Чтобы описать все формы, которые может принимать свойство вариантности необходимо определить, как типы могут соотноситься с друг другом. Здесь и далее под типом я понимаю любой ссылочный тип или производный от него. Если экземпляр типа T можно заменить экземпляром типа U, то мы будем считать, что U < T. Если экземпляр U можно заменить экземпляром T, то U > T. Если обе замены возможны, то U = T. Если ни одна не возможна, то типы T и U не сравнимы.

Преобразование, осуществляемое оператором, является:

  • Ковариантным, если сохраняет отношение между парой типов после их преобразования в производные
  • Контравариантным, если обращает отношение «меньше» на «больше» и сохраняет «равны» и «не сравнимы»
  • Бивариантным, если отношения «меньше» и «больше» обращает в «равны» и сохраняет «равны» и «не сравнимы»
  • Инвариантным, если сохраняет «равно», а любое другое отношение обращает в «не сравнимы»

Примеры, кратко

Несколько примеров применения такого определения:

  • Оператор T[] ковариантно преобразует T, поэтому можно заменить экземпляр Object[] на экземпляр String[]
  • Оператор Action<T> контравариантно преобразует T, поэтому можно заменить Action<String> на Action<Object>
  • Оператор Func<T,U> ковариантно преобразует возвращяемый тип U и контравариантно преобразует тип передаваемого аргумента T. Поэтому можно заменить Func<String,Object> на Func<Object, String>
  • Оператор U MyMethod(T t) инвариантно преобразует как возвращаемый тип T, так и тип передаваемого аргумента U. Поэтому нельзя перегрузить метод Object MyMethod(String) методом String MyMethod(Object)

Конец

Надеюсь, что сформулированное определение сможет помочь в изучении вопроса вариантности, на ряду с ресурсами, которые я использовал для создания этой заметки:


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/pesochnitsa/82778

Ссылки в тексте:

[1] Eric Lippert's Blog, Covariance and Contravariance in C#, Part One: http://blogs.msdn.com/b/ericlippert/archive/2007/10/16/covariance-and-contravariance-in-c-part-one.aspx

[2] Eric Lippert's Blog, Covariance and Contravariance in C#, Part Two: Array Covariance: http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx

[3] Eric Lippert's Blog, Covariance and Contravariance in C#, Part Three: Method Group Conversion Variance: http://blogs.msdn.com/b/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx

[4] Eric Lippert's Blog, Covariance and Contravariance in C#, Part Four: Real Delegate Variance: http://blogs.msdn.com/b/ericlippert/archive/2007/10/22/covariance-and-contravariance-in-c-part-four-real-delegate-variance.aspx

[5] Джон Скит, C# Для Профессионалов: http://csharpindepth.com/

[6] Wikipedia, Covariance and contravariance (computer science): http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)

[7] MSDN, Covariance and Contravariance: https://msdn.microsoft.com/en-us/library/ee207183.aspx