C#泛型类型约束这不是应该是有效的C#代码吗?classAwhereT:class{publicvoidDoWork()whereK:T{varb=newB();//<-编译时错误}}classBwhereU:class{}编译器吐出此错误:错误CS0452:类型'K'必须是引用类型才能将其用作泛型类型或方法中的参数'U''ConsoleApplication1.B'编译器是否应该能够确定K是否被约束为T类型或派生自T,因此它显然应该是引用类型(T被约束为引用类型)?指定类型参数时将应用约束。虽然为U指定了K,但是并没有为K指定类型。由于U要求它的类型是引用类型,所以编译器想确认K确实是引用类型,但是不能。因此,您需要明确声明它将是。规范在第4.4.4节中指出:对于每个where子句,针对每个约束检查与命名类型参数对应的类型参数A。然后:如果给定的类型参数不满足一个或多个类型参数的约束,就会发生编译时错误。因为它不继承类型参数,所以它也不继承约束。最后一点表明K不继承T的约束。更新虽然我的结论似乎是正确的,但我的证据有点站不住脚,正如EricLippert的回复中现已删除的回复所澄清的那样。Eric说规范的正确部分是:如果类型参数具有引用类型约束或其有效基类不是Object或System.ValueType,则类型参数已知为引用类型。我之前的回答不正确;我删了它。感谢userconfigurator指出我的错误。编译器难道不应该能够确定K是被约束为类型T还是从T派生,所以它显然应该是一个引用类型(T被约束为一个引用类型)?否。K被限制为类型T或派生自T的类型。T被限制为引用类型。这并不意味着K是引用类型。即:object是引用类型,int是object的派生类型。如果T是object,K可以是int,不是引用类型。约束不会以这种方式级联。每个通用签名都有自己独特的约束,这些约束独立于可能暗示的任何子约束进行评估。你需要一个关于K以及T和U的类声明,即使它已经暗示了T。试试这个://whereU:class{}不幸的是,编译器似乎不够聪明,无法推断出这一点。但是,如果您向K添加更多约束,您就可以开始了。我认为您需要指定K:class和T.classAwhereT:class{publicvoidDoWork()whereK:class,T{varb=newB();//whereU:class{}你应该这样做:classAwhereT:class{publicvoidDoWork()whereK:class,T{varb=newB();//whereU:class{}编辑:如果你没有将K指定为一个类并且没有参数构造函数,那么你将出现编译时错误:typeUmustbereftype,andneedstohaveaparameterlessconstructor以上是C#学习教程的全部内容:C#泛型类型约束。更多关于C#学习教程,希望大家多多关注—本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
