C#学习教程:其中t:类generics约束和const值声明分享


其中t:类generics约束和const值声明

根据10.4 Constants C#规范:

常量声明中指定的类型必须是 sbyte,byte,short,ushort,int,uint,long,ulong,char,float,double,decimal,bool,string,enum-type 或reference-type。 每个常量表达式必须生成目标类型或可通过隐式转换(第6.1节)转换为目标类型的类型的值。

为什么我不能做以下事情:

 public class GenericClass where T : class { public const T val = null; } 

这应该是可能的,因为:

任何可能的解释?

可能的解释

考虑CLR如何初始化generics类的static成员,或者在generics类型上调用静态构造函数时。 通常,首次加载程序时会发生静态初始化; 但是,generics类在第一次创建该类的实例时初始化其静态成员。

请记住,generics类不是单一类型; 在类型声明中传递的每个T都在创建一个新类型。

现在考虑一个const表达式,它需要在编译时进行求值。 尽管T被约束为一个类,因此它可以接收值null,但是在运行时创建类之前,变量val不存在于内存中。

例如,考虑const T val是否有效。 然后我们可以使用代码中的其他地方:

 GenericClass.val GenericClass.val 

编辑

虽然两个表达式的值都为null ,但前者的类型为string ,后者的类型为object 。 为了使编译器执行替换,它需要知道所讨论的常量的类型定义。

约束可以在编译时强制执行,但是开放generics在运行时之前不会转换为封闭的generics。 因此, GenericClass.val不能存储在编译器的本地内存中以执行替换,因为编译器不会实例化generics类的闭合forms,因此不知道将常量表达式实例化的类型。

Eric Lippert承认这是一个bug,应该允许:

它看起来像你发现了一个bug; 要么bug在规范中,哪个应该显式地调用类型参数不是有效类型,或者bug在编译器中,应该允许它。

上述就是C#学习教程:其中t:类generics约束和const值声明分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—猴子技术宅(www.ssfiction.com)

本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

如若转载,请注明出处:https://www.ssfiction.com/ckf/960149.html

发表评论

邮箱地址不会被公开。 必填项已用*标注