尝试对无法转换的非泛型类型使用C#"as"关键字时,编译器会提供无法转换类型的错误.
但是,当对泛型类型使用"as"关键字时,编译器不会给出错误:
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
}
}
Run Code Online (Sandbox Code Playgroud)
我在更大的代码库中发现了这种行为,其中缺少编译时错误导致运行时出现问题.
设计是否存在冲突行为?如果是这样,有没有人知道为什么?
在§7.10.11 The as operatorC#5.0规范中说:
在E形式的操作中,E必须是表达式,T必须是引用类型,已知为引用类型的类型参数或可空类型.此外,必须至少满足下列条件之一,否则会发生编译时错误:
标识(第6.1.1节),隐式可空(第6.1.4节),隐式引用(第6.1.6节),装箱(第6.1.7节),显式可空(第6.2.3节),显式引用(第6.2节). 4),或从E到T的拆箱(§6.2.5)转换.
E或T的类型是开放型.
E是空文字.
所以args as Foo给出一个错误,因为这都不是真的.但在第二种情况下,Bar<T>是一个开放类型,并且规范解释开放类型为§4.4.2 Open and closed types:
开放类型是涉及类型参数的类型.进一步来说:
- 类型参数定义开放类型.[...]