2

我在业余时间正在研究一个交互式编译器,我发现我可以使用 a 定义一个类型,TypeBuilder它定义了两个具有相同名称的字段(并且该类型显然会发出并运行它的初始化程序,这些静态字段被初始化,只是美好的) 。查看我的监视窗口:

在此处输入图像描述

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

4

1 回答 1

5

这在ECMA-335 CLI 规范的§I.8.5.2 中有解释:

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

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

我理解这一点的方式,这意味着您可以在同一类型中拥有两个具有相同名称的不同字段,但它们必须具有不同的签名,即不同的类型。因此,如果您有两个字段string xint x,那么根据 CLI 规范就可以了。根据公共语言规范 (CLS) 是不行的,但这基本上只是一组使语言互操作性更容易的规则。

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

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

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

于 2013-07-05T11:16:02.827 回答