如何在CIL中声明一个值类型:`.class value`或只是`.class`?

时间:2013-02-22 14:10:54

标签: syntax definition cil value-type ilasm

我看了ILDASM中的C#struct FooStruct,并看到了以下内容:

enter image description here

ILDASM在这里显示两个不同的声明:

  • .class value public开头(后窗和前窗标题栏)
  • .class public(前窗)
  • 开头

我想知道哪种语法(如果不是两者)都是用于声明值类型的正确语法? value修饰符是严格必需的,还是可选的,还是语法错误?

2 个答案:

答案 0 :(得分:3)

  

简答:值类型定义只需要extends [mscorlib]System.ValueType; value属性似乎是可选的,没有明显效果。

我认为CLI规范(ECMA-335)是寻找认可答案的最佳位置。

值类型定义必须包含value属性吗?

第II.10节涉及定义类型。更具体地说,第II.10.1.3小节规定:

  

类型语义属性指定是否应定义接口,类或值类型。 ...如果[interface]属性不存在且定义扩展   (直接或间接)System.ValueType,且定义不适用于System.Enum,应定义值类型(§II.13)。否则,应定义一个类(§II.11)。

整个部分根本没有提到value属性。

结论:正确的值类型定义不必包含value。从System.ValueType派生就足够了。

可以是值类型定义包括value修饰符吗?

CLI标准还包含ILASM的语法(在第VI.C.3节中)。根据该语法,value类型定义存在.class属性。我还搜索了标准的具体值类型定义,并找到了这些例子:

  • .class public sequential ansi serializable sealed beforefieldinit System.Double extends System.ValueType …
  • .class private sealed Rational extends [mscorlib]System.ValueType …
  • .class value sealed public MyClass extends [mscorlib]System.ValueType …

结论value属性可能包含在值类型定义中。

value属性是什么意思?

我尝试将这三个IL类型定义编译成一个程序集:

.class       public sealed … A extends [mscorlib]System.ValueType { … }
.class value public sealed … B extends [mscorlib]System.ValueType { … }
.class value public sealed … C extends [mscorlib]System.Object    { … }  // !!!

即使在引用类型声明中使用value属性,也没有编译错误(请参阅最后一行)。使用Visual Studio 2012的对象浏览器查看生成的程序集会显示两种值类型(structAB,以及一种引用类型(classC

猜测: value属性的存在对类型定义没有任何影响。它只是作为人类发现价值类型定义的潜在帮助。

答案 1 :(得分:2)

这个伟大的book包含简单 回答:当你提供extends子句时,忽略value标志,但如果你没有提供 extends并使用value然后ilasm会将给定类型声明为值类型。

换句话说,value被引入为语法糖,以快速声明值类型。