我在业余时间处理交互式编译器,我发现我可以使用TypeBuilder
定义一个类型,它定义了两个具有相同名称的字段(类型显然发出并运行其初始化程序,这些静态字段初始化的地方就好了。看我的观察窗口:
我发现这很奇怪:具有两个同名字段的类型有什么实际用途?根据CLR规范(对参考感兴趣),这真的是“合法的”,还是TypeBuilder
可能不允许的这种未定义或非法的行为?
答案 0 :(得分:4)
通常,名称不是唯一的。名称被收集到名为的分组中 范围。在范围内,名称可以引用多个实体,只要它们具有不同的种(方法,字段,嵌套类型,属性和事件)或具有不同的签名。
CLS规则5 :符合CLS的范围中引入的所有名称应独立于种类,除非名称相同且通过重载解析。也就是说,虽然CTS允许单个类型对方法和字段使用相同的名称,但CLS不允许。
我理解这一点的方式,意味着您可以在同一类型中拥有两个具有相同名称的不同字段,但它们必须具有不同的签名,即不同的类型。因此,如果您有两个字段string x
和int x
,那么根据CLI规范,这没关系。根据公共语言规范(CLS),它并不合适,但这基本上只是一组使语言互操作性更容易的规则。
另一方面,具有两个具有相同名称和类型的字段的类型是不合法的,如果在具有类似类型的程序集上运行PEVerify,它确实无法验证:
[MD]:错误:字段有重复,令牌= 0x04000002。 [令牌:0x04000001]
[MD]:错误:字段有重复,令牌= 0x04000001。 [令牌:0x04000002]
出于某种原因,似乎CLR没有进行此检查,因此它允许这样的无效类型。 C#编译器也能够处理这样的类型,它似乎选择了两个字段中的一个并使用它。