问题
When attempting to use the C# "as" keyword against a non-generic type that cannot be cast to, the compiler gives an error that the type cannot be converted.
However when using the "as" keyword against a generic type the compiler gives no error:
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
}
}
I discovered this behaviour in a much larger code base where the lack of a compile time error led to an issue at runtime.
Is the conflicting behaviour by design? If so, does anyone have any insight as to why?
回答1:
In §7.10.11 The as operator C# 5.0 Specification says:
In an operation of the form E as T, E must be an expression and T must be a reference type, a type parameter known to be a reference type, or a nullable type. Furthermore, at least one of the following must be true, or otherwise a compile-time error occurs:
An identity (§6.1.1), implicit nullable (§6.1.4), implicit reference (§6.1.6), boxing (§6.1.7), explicit nullable (§6.2.3), explicit reference (§6.2.4), or unboxing (§6.2.5) conversion exists from E to T.
The type of E or T is an open type.
E is the null literal.
So args as Foo gives an error because none of this is true. But in the second case, Bar<T> is an open type, and the spec explains open type as, §4.4.2 Open and closed types :
An open type is a type that involves type parameters. More specifically:
- A type parameter defines an open type. [...]
回答2:
"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."
https://msdn.microsoft.com/en-us/library/cscsdfbt.aspx
来源:https://stackoverflow.com/questions/28149927/conflicting-compile-time-behaviour-using-as-keyword-against-generic-types-in-c-s