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:“功能需要时间来实现。”