为何字段与枚举类型同名时,非可空字段可引用枚举值,可空字段却编译失败?
为何字段与枚举类型同名时,非可空字段可引用枚举值,可空字段却编译失败?
这个问题不是bug哦,核心原因在于C#编译器的名称解析规则,咱们慢慢拆解来看:
类A能正常编译的原因
你在类A里定义了和枚举同名的字段ControlType,当写ControlType.Foo初始化字段时,编译器会先尝试把ControlType当成当前类的实例字段。但这里有个问题:值类型的字段在未完成初始化时,根本无法访问它的成员(比如Foo),这种引用在语义上完全无效。所以编译器会“自动退一步”,把ControlType解析为外部的枚举类型,这样就能正确拿到Foo枚举值,自然编译通过。类B编译失败的原因
类B里的字段是可空值类型ControlType?,当你写ControlType.Foo时,编译器会优先匹配当前类的ControlType实例字段(因为字段名和标识符完全一致)。这时候编译器不会像处理非可空值类型那样回溯——它认为你是在引用这个实例字段并试图访问它的Foo成员,但字段初始化器不允许引用非静态的实例成员(毕竟此时类的实例还没创建出来,字段根本不存在),所以就抛出了CS0236的编译错误。
简单来说,字段初始化器中的名称解析有优先级:编译器会先找当前类的实例成员,只有当这种引用完全不可行时,才会去匹配外部类型。类A的情况属于“引用实例成员完全不可行”,所以编译器切换到类型解析;类B的情况则是“引用实例成员在语法上可行,但违反了初始化规则”,因此直接报错。
备注:内容来源于stack exchange,提问作者TN.
相关产品推荐
相关产品推荐

