Конфликтующее поведение времени компиляции, использующее в качестве ключевого слова для общих типов в С#
При попытке использовать ключевое слово С# "как" для не-генерического типа, который не может быть применен, компилятор выдает ошибку, что тип не может быть преобразован.
Однако при использовании ключевого слова "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
}
}
Я обнаружил это поведение в гораздо большей кодовой базе, где отсутствие ошибки времени компиляции привело к проблеме во время выполнения.
Является ли конфликтное поведение по дизайну? Если да, то кто-нибудь может понять, почему?
Ответы
Ответ 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