我正在业余时间开发一个交互式编译器,我发现我可以使用 TypeBuilder
定义一个类型,它定义两个具有相同名称的字段(并且该类型显然会发出并运行它的初始化程序,这些静态字段在其中初始化,就好了)。查看我的观看窗口:
我觉得这很奇怪:具有两个同名字段的类型有什么实际用途?根据 CLR 规范,这真的“合法”吗(对引用感兴趣),还是 TypeBuilder
可能不允许这种未定义或非法行为?
最佳答案
这在 ECMA-335 CLI specification 的 §I.8.5.2 中进行了解释:
Generally, names are not unique. Names are collected into groupings called scopes. Within a scope, a name can refer to multiple entities as long as they are of different kinds (methods, fields, nested types, properties, and events) or have different signatures.
CLS Rule 5: All names introduced in a CLS-compliant scope shall be distinct independent of kind, except where the names are identical and resolved via overloading. That is, while the CTS allows a single type to use the same name for a method and a field, the CLS does not.
按照我的理解,这意味着您可以在同一类型中拥有两个具有相同名称的不同字段,但它们必须具有不同的签名,即不同的类型。因此,如果您有两个字段 string x
和 int x
,根据 CLI 规范这是可以的。根据公共(public)语言规范 (CLS),这是不行的,但这基本上只是一组使语言互操作性更容易的规则。
另一方面,具有两个具有相同名称和类型的字段的类型是不合法的,如果您在具有此类类型的程序集上运行 PEVerify,它确实会失败验证:
[MD]: Error: Field has a duplicate, token=0x04000002. [token:0x04000001]
[MD]: Error: Field has a duplicate, token=0x04000001. [token:0x04000002]
出于某种原因,CLR 似乎没有进行此检查,因此它允许此类无效类型。 C# 编译器也能够处理此类类型,似乎它选择两个字段之一并使用它。
关于.net - TypeBuilder 允许定义两个同名字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17480433/