Подтвердить что ты не робот

Аннотации вариации С# параметра типа, ограниченного типом значения

В С# возможно добавить аннотацию вариации к типу type, ограниченному типом значения:

interface IFoo<in T> where T : struct
{
  void Boo(T x);
}

Почему это разрешено компилятором, если аннотация аннотации не имеет абсолютно никакого смысла в такой ситуации?

4b9b3361

Ответ 1

Почему это разрешено компилятором, поскольку аннотация аннотации не имеет абсолютно никакого смысла в такой ситуации?

Это разрешено компилятором, потому что я даже не думал, что кто-то попытается это сделать, когда я добавлю правила дисперсии компилятору С# 4.0.

Предупреждения и ошибки компилятора - это функции, и для того, чтобы функция была реализована, она должна, как минимум, считаться в какой-то момент перед отправкой вашего компилятора. Я не сделал этого и поэтому никогда не имел возможности даже обсуждать, должно ли быть предупреждение для такой ситуации.

Теперь, когда вы привлекли мое внимание, возникает вопрос: должна ли это быть особенность? Должен ли компилятор выдавать предупреждение (или ошибку) для этого случая?

Это призыв к суду. Мы рассмотрим несколько вещей:

  • Является ли код тем, что кто-то может набрать, думая, что он делает что-то разумное? Никто не надеется; можно надеяться, что разработчик, который знает достаточно о системе типов для создания варианта интерфейса, также знает, что дисперсия работает только с ссылочными типами. Но, возможно, есть разработчики, которые могут набрать это, думая, что это сработает. По крайней мере, это не кажется правдоподобным. Это явно не придумано.

  • Является ли код явно неправильным? Да, возможно. Кажется очень маловероятным, что кто-то намеренно хочет написать интерфейс, который выглядит вариант, но на самом деле это не так.

И так далее.

Мне придется больше подумать, но на первый взгляд похоже, что это может быть достойным предупреждением для добавления в компилятор. Я поговорю с командой, и мы рассмотрим возможность добавления ее в версию Roslyn.

Спасибо за идею!

Ответ 2

Это разрешено просто потому, что это легальный код. В этом нет никакого вреда. Да, вы не можете использовать контравариантное преобразование, но я не вижу проблемы. Ничто в коде не будет вводить в заблуждение или скрывать какую-то искаженную информацию.

Я просто думаю, что компилятор не проверяет, является ли тип T типом значения или ссылочным типом при проверке действительности валидации. Разумеется, команда С# предположила, что любой, кто использует общую дисперсию интерфейса, будет знать, что делать это с типами значений бессмысленно и в любом случае не имеет вторичных эффектов.