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

Конфликтующее поведение времени компиляции, использующее в качестве ключевого слова для общих типов в С#

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

Однако при использовании ключевого слова "as" для генерического типа компилятор не дает ошибки:

public class Foo { }

public class Bar<T> { }

public class Usage<T> {
   public void Test() {
      EventArgs args = new EventArgs();
      var foo = args as Foo;     // Compiler Error: cannot convert type
      var bar = args as Bar<T>;  // No compiler error
   }
}

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

Является ли конфликтное поведение по дизайну? Если да, то кто-нибудь может понять, почему?

4b9b3361

Ответ 1

В §7.10.11 The as operator Спецификация С# 5.0:

В операции вида E как T, E должно быть выражением, а T должно быть ссылочным типом, параметром типа, который известен как ссылочный тип, или тип с нулевым значением. Кроме того, по крайней мере одно из следующего должно быть истинным или иначе возникает ошибка времени компиляции:

  • Идентичность (§6.1.1), неявная нулевая (§6.1.4), неявная ссылка (§6.1.6), бокс (§6.1.7), явный nullable (§6.2.3), явный ссылка (§6.2.4) или разблокировка (§6.2.5) существует от E до Т.

  • Тип E или T - открытый тип.

  • E - нулевой литерал.

Итак, args as Foo дает ошибку, потому что ни одно из этого не является истинным. Но во втором случае Bar<T> является открытым типом, а spec объясняет открытый тип как, §4.4.2 Open and closed types:

Открытый тип - это тип, который включает параметры типа. Более конкретно:

  • Параметр type определяет открытый тип. [...]

Ответ 2

"Обратите внимание, что оператор as выполняет только ссылочные преобразования, конверсии с нулевым значением и преобразования в бокс. Оператор as не может выполнять другие преобразования, такие как пользовательские преобразования, которые вместо этого должны выполняться с использованием выражений выражений."

https://msdn.microsoft.com/en-us/library/cscsdfbt.aspx