I asked this question. This code doesn't compile ("Cannot convert Generic<T>
to T
") because of the reason explained here (even if I'd expect an InvalidCastException
at run-time instead of a compile-time error).
class NonGeneric
{
}
class Generic<T> : NonGeneric
where T : NonGeneric
{
T DoSomething()
{
return (T)this; // ** Cannot convert...
}
}
Accepted solution gave this workaround:
T DoSomething()
{
return this as T;
}
My question is: why? as
operator should be exactly equivalent to cast operator:
The as operator is like a cast operation. However, if the conversion isn't possible, as returns null instead of raising an exception.
If this as T
should be equivalent to this is T? (T)this: (T)null
then why as T
works and (T)this
doesn't even compile? AFAIK cast could be used in a more wide range of situations than as
:
Note that the as operator performs only reference conversions, nullable conversions, and boxing conversions. The as operator can't perform other conversions, such as user-defined conversions, which should instead be performed by using cast expressions.
Then why this? Is it a documented feature of as
operator? Is it a compiler/language limitation with generic types? Note that this code compiles fine:
return (T)((object)this);
Is this because compiler can't be sure if T
is dynamic
(even if there is a where
constraint) then it'll always generate such code?
'as' operator in C# performs these actions:-
'as' operator is slightly faster than any casting (even in cases where there are no invalid casts which would severely lower casting's performance due to exceptions).
It says in the C# Language Specification (emphasis mine),
This seems to be the reason why the compilation succeed using
as
or whenthis
is cast to an object first. Furthermore,Which is the current case with your generic class.
According to msdn:-
Another difference is that:-