考虑以下通用方法:
public T2 Frob<T1,T2>(T1 item) where T1 : class,T2 => item as T2;
编译器将拒绝编译此代码;类型参数“T2”不能与“as”运算符一起使用,因为它不具有类类型约束或“类”约束
好的,这很容易解决:
public T2 Frob<T1,T2 where T2 : class => item as T2;
但这不是多余的吗?考虑到T1已经存在的限制,是否有可能的T2不是类?
我的问题不是为什么这个“推理”没有在编译器中实现,原因可能只是“没有人想到”,这样可以.我更感兴趣的是,我的推理是正确的,因为T2是有效的,在所有情况下都被限制在第一个例子中的类,即使它没有明确强制执行.
解决方法
我对此的解释,给出C#5.0规范说的是7.10.11,作为运算符:
In an operation of the form
E as T
,E
must be an expression andT
must be a reference type,a type parameter known to be a reference type,or a nullable type.
此时的编译器只考虑此块中的T2:
public T2 Frob<T1,T2 => item as T2;
它看到T2本身并不受限制.当然,可以扣除,在这种情况下,T1预计是一个参考类型并继承T2,因此T2本身也应该是一个参考类型,但我肯定有理由不这样做.