C# 冗余泛型约束?
考虑以下通用方法:C# 冗余泛型约束?,c#,generics,type-constraints,C#,Generics,Type Constraints,考虑以下通用方法: public T2 Frob<T1, T2>(T1 item) where T1 : class, T2 => item as T2; 公共T2 Frob(T1项) 式中T1:class,T2 =>项目为T2; 编译器将拒绝编译此代码;类型参数“T2”不能与“as”运算符一起使用,因为它既没有类类型约束,也没有“class”约束 好的,这很容易解决,只需执行以下操作: public T2 Frob<T1, T2>
public T2 Frob<T1, T2>(T1 item)
where T1 : class, T2
=> item as T2;
公共T2 Frob(T1项)
式中T1:class,T2
=>项目为T2;
编译器将拒绝编译此代码;类型参数“T2”不能与“as”运算符一起使用,因为它既没有类类型约束,也没有“class”约束
好的,这很容易解决,只需执行以下操作:
public T2 Frob<T1, T2>(T1 item)
where T1 : class, T2
where T2 : class
=> item as T2;
公共T2 Frob(T1项)
式中T1:class,T2
其中T2:类
=>项目为T2;
但这不是多余的吗?考虑到T1
已有的约束条件,是否有任何可能的T2
不是类
我的问题不是为什么这个“推断”没有在编译器中实现,原因可能只是“没有人考虑过”,这没关系。我更感兴趣的是知道我的推理是否正确,因为在第一个示例中,
T2
是有效的,并且在所有情况下都被约束到类
,即使它没有明确强制执行。我对这一点的解释,考虑到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 Frob(T1项)
式中T1:class,T2
=>项目为T2;
它发现
T2
本身并不受约束。当然,它可以推断,在这种情况下,T1
应该是一个引用类型,并继承T2
,因此,T2
本身也应该是一个引用类型,但我确信有理由不这样做。@HimBromBeere给我一个从值类型派生的引用类的示例,因为这正是在T1
@HimBromBeere的约束条件下必须发生的事情,我认为OP的意思是T2
不能是值类型,因为T1
不能从值类型派生。所以它必须是一种引用类型。我个人认为这些问题“主要是基于观点的”,但关于“为什么C#设计器在编译器中实现X”的问题之前已经得到了回答。。。“我知道什么。@Jamiec如果你读了我的问题,我不是在问编译器为什么需要冗余约束。我想问的是,它是否是多余的,或者是否存在一些非常奇怪的情况,而不是这样。我想不出有什么办法,但我想100%肯定。不管怎样,你都会问为什么一个人会这样做,或者说他是否有疏忽。这是一个动机的问题,唯一能回答这个问题的人是实施它的人。实际上,除了Eric Lippert在回答中指出的以外,可能没有其他理由这么做:。TL;DR:“功能需要时间来实现。”