考虑以下通用方法:
public T2 Frob<T1, T2>(T1 item)
where T1 : class, T2
=> item as T2;
编译器将拒绝编译此代码; 类型参数&#39; T2&#39;不能用于&#39; as&#39;运算符,因为它没有类类型约束,也没有&#39;类&#39;约束
好的,这很容易解决:
public T2 Frob<T1, T2>(T1 item)
where T1 : class, T2
where T2 : class
=> item as T2;
但这不是多余的吗?考虑到T2
已经存在的约束,是否有class
可能不是T1
?
我的问题不是为什么这个&#34;推理&#34;没有在编译器中实现,原因可能只是“没有人想到它&#34;那没关系。我更有兴趣知道我的推理是否正确,T2
是否有效且在所有情况下在第一个示例中被约束为class
,即使它没有明确说明执行。
答案 0 :(得分:4)
我对此的解释,鉴于C#5.0规范在7.10.11,as
运算符:
在表单
E as T
的操作中,E
必须是表达式,T
必须是引用类型,已知为引用类型的类型参数,或者是可以为空的类型。
此时编译器仅考虑此块中的T2
:
public T2 Frob<T1, T2>(T1 item)
where T1 : class, T2
=> item as T2;
它发现T2
本身并不受约束。当然,它可以扣除,在这种情况下,T1
应该是引用类型并且继承T2
,因此T2
本身也应该是一种参考类型,但我确信有理由不这样做。