I have just posted an answer to this question but I'm not entirely convinced of my answer.There are two things I'm wondering, consider this code:
class Foo<T>
{
void SomeMethod()
{
string str = "foo";
Foo<T> f = str as Foo<T>;
}
}
According to C# Specification 5.0
, there are two different kinds of conversion of as operator
.
If the compile-time type of
E
is notdynamic
, the operationE as T
produces the same result asE is T ? (T)(E) : (T)null
If the compile-time type of
E
isdynamic
, unlike the cast operator theas operator
is not dynamically bound (§7.2.2). Therefore the expansion in this case is:E is T ? (T)(object)(E) : (T)null
Since, this is invalid because of (Foo<T>)str
str is Foo<T> ? (Foo<T>)str : (Foo<T>)null;
I thought it should be translated as:
str is Foo<T> ? (Foo<T>)(object)str : (Foo<T>)null;
But the spec says this only happens when the type of E
is dynamic
.
So my questions are:
- Is the compiler translating this expression to a code that is normally invalid?
- When the type of
E
is dynamic why first it castsE
toobject
thenT
while the(T)E
is completely valid?