Я только что отправил ответ на этот вопрос, но я не совсем уверен в своем ответе. Есть две вещи, которые мне интересно, рассмотрите этот код:
class Foo<T>
{
void SomeMethod()
{
string str = "foo";
Foo<T> f = str as Foo<T>;
}
}
Согласно C# Specification 5.0, существует два разных типа преобразования as operator.
Если тип времени компиляции
Eнеdynamic, операцияE as Tдает тот же результат, что иE is T ? (T)(E) : (T)nullЕсли тип времени компиляции
Eравенdynamic, в отличие от оператора трансляцииas operatorне динамически связан (§7.2.2). Поэтому разложение в этом случае есть:E is T ? (T)(object)(E) : (T)null
Так как это недопустимо из-за (Foo<T>)str
str is Foo<T> ? (Foo<T>)str : (Foo<T>)null;
Я думал, что это нужно перевести как:
str is Foo<T> ? (Foo<T>)(object)str : (Foo<T>)null;
Но спецификация говорит, что это происходит только тогда, когда тип E равен dynamic.
Итак, мои вопросы:
- Является ли компилятор преобразованием этого выражения в код, который обычно недействителен?
- Когда тип
Eявляется динамическим, почему сначала он отбрасываетEвobject, а затемT, а(T)Eявляется полностью допустимым?