Я только что отправил ответ на этот вопрос, но я не совсем уверен в своем ответе. Есть две вещи, которые мне интересно, рассмотрите этот код:
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
является полностью допустимым?