.net TypeBuilder允许定义两个同名字段

.net TypeBuilder允许定义两个同名字段,.net,clr,reflection.emit,.net,Clr,Reflection.emit,我在业余时间从事一个交互式编译器的工作,我发现我可以使用TypeBuilder定义一个类型,该类型定义了两个同名字段(该类型显然会发出并运行其初始值设定项,在这里这些静态字段被初始化,很好)。查看我的手表窗口: 我觉得这很奇怪:一个具有两个同名字段的类型有什么实际用途?根据CLR规范,这真的是“合法”的吗(有兴趣参考),或者这是TypeBuilder可能不允许的未定义或非法行为吗?这在以下文件的§I.8.5.2中解释: 通常,名称不是唯一的。名称被收集到称为 范围。在一个范围内,一个名称可以引

我在业余时间从事一个交互式编译器的工作,我发现我可以使用
TypeBuilder
定义一个类型,该类型定义了两个同名字段(该类型显然会发出并运行其初始值设定项,在这里这些静态字段被初始化,很好)。查看我的手表窗口:


我觉得这很奇怪:一个具有两个同名字段的类型有什么实际用途?根据CLR规范,这真的是“合法”的吗(有兴趣参考),或者这是
TypeBuilder
可能不允许的未定义或非法行为吗?

这在以下文件的§I.8.5.2中解释:

通常,名称不是唯一的。名称被收集到称为 范围。在一个范围内,一个名称可以引用多个实体,只要它们是不同类型(方法、字段、嵌套类型、属性和事件)或具有不同的签名

CLS规则5:在符合CLS的范围内引入的所有名称应独立于种类而不同,除非名称相同并通过重载解析。也就是说,虽然CTS允许单个类型对方法和字段使用相同的名称,但CLS不允许

按照我的理解,这意味着在同一类型中可以有两个同名的不同字段,但它们必须具有不同的签名,即不同的类型。因此,如果您有两个字段
stringx
intx
,根据CLI规范,这是可以的。根据公共语言规范(CLS),这是不好的,但这基本上只是一组使语言互操作性更容易的规则

另一方面,具有两个字段且具有相同名称和类型的类型是不合法的,如果在具有类似类型的程序集上运行PEVerify,则验证确实失败:

[MD]:错误:字段有重复项,标记=0x04000002。[令牌:0x04000001]
[MD]:错误:字段有重复项,标记=0x04000001。[令牌:0x04000002]


出于某种原因,CLR似乎没有进行此检查,因此它允许此类无效类型。C#编译器也能够处理此类类型,似乎它从两个字段中选择一个并使用它。

为两个不同的字段使用相同名称的一个实际原因是代码混淆。我希望它在元数据系统加载类时抛出。如果没有,那么它可能是合法的。无论如何,我假设CLR使用句柄来标识字段/方法/属性,而不是名称。因此,只要生成所有内容并使用句柄或偏移来更正成员,就应该可以了。但是,如果有人用名字来称呼它,比如通过DLR,那么它可能会抛出含糊不清的匹配。我偶然发现,有人说这是TypeBuilder的“设计”和“你必须处理它”。仍然没有提到在CLR层它是非法的。