关于拳击的CLR规范

时间:2011-10-05 11:31:27

标签: .net c++-cli clr value-type boxing

我正在阅读CLR specification。我在理解“I 8.2.4拳击和拆箱价值”部分时遇到了一些麻烦。

1。何时可以使用盒装类型?

一方面它声明:

  

对于每种值类型,CTS定义一个称为盒装类型的相应引用类型。 [...] a的值的表示   盒装类型(盒装值)是可以存储值类型值的位置。盒装类型是   对象类型和盒装值是一个对象。

     

无法通过名称直接引用盒装类型,因此不能为盒子提供任何字段或局部变量   类型。最接近盒装枚举值类型的命名基类是System.Enum;对于所有其他值类型   它是System.ValueType。键入的字段System.ValueType只能包含空值或a的实例   盒装值类型。键入的本地System.Enum只能包含空值或盒装实例   枚举类型。

这是否意味着我可以拥有使用强类型盒装值类型的属性/方法,或者这只是规范中的遗漏?如果是这样,为什么我可以拥有属性而不是字段?

另一方面,即使在使用MyStruct^ but seems to behave strangely with boxed primitive types(System.Int32^)的局部变量中,C ++ / CLI似乎也支持盒装值类型。但是我不确定C ++ / CLI编译器魔法的哪一部分(它可能使用标记的Object变量),哪部分是CLR处理。

该规范进一步指出:

  

CLS规则3:盒装值类型不符合CLS。   [注意:代替盒装类型,请根据需要使用System.Object,System.ValueType或System.Enum。

这似乎暗示强类型盒装值类型可以是类型的公共接口的一部分。但不应该用于CLS合规性(这是可以理解的,因为大多数语言不支持它们)。

那么在哪里可以使用强类型盒装值类型?为什么它可以用在那些地方,而不是其他地方?

2。拳击参考类型

该规范还提到拳击参考类型:

  

如果类型是以下之一,则该类型是可装箱的:

     

[...]

     
      
  • 引用类型(包括类,数组,委托和泛型类的实例化),不包括   托管指针/ byrefs(§8.2.1.1)

  •   
  • 通用参数(通用类型定义或通用方法定义)[注意:拳击和   拆箱通用参数会增加CLI实现的性能开销。受约束。   通过避免,前缀可以在虚拟分派到由值类型定义的方法期间提高性能   装箱值类型。结束说明]

  •   

拳击参考类型是否为无操作?允许装箱参考类型对于通用参数很有用,在这些参数中您不知道某些东西是值还是引用类型。因此,我假设装箱参考类型与表示参考类型的通用参数保持一致。

3。接口“在类型上定义”是什么意思?

最后我在理解以下段落时遇到了问题:

  

接口和继承仅在引用类型上定义。因此,虽然值类型定义(第8.9.7节)可以   指定两个应由值类型和类实现的接口(System.ValueType或   它继承的System.Enum),仅适用于盒装值。

“在类型上定义”的界面是什么意思?我的理解是,转换为接口/基类会对值进行处理,但您仍然可以使用受约束的虚拟调用来调用未装箱的此类接口/类中定义的方法。 (带有约束前缀的virtcall)

1 个答案:

答案 0 :(得分:4)

是的,C ++ / CLI语言允许声明强类型的盒装值类型:

public ref class Class1
{
public:
    int^ boxedInt;
    Class1() { boxedInt = 42; }
};

它遵守CLI规范,但 boxedInt 字段在元数据中键入ValueType。它记住并检查带有modOpt属性的盒装类型:

field boxedInt: public class System.ValueType modopt(System.Int32) modopt(System.Runtime.CompilerServices.IsBoxed)

在C#中可能完全相同,减去编译器检查只有int值被赋给字段。只需将该字段声明为ValueType即可。否则这没有实际价值。

相关问题