我目前正在阅读 CLR specification 。我在理解“I 8.2.4 值的装箱和拆箱”部分时遇到了一些麻烦。
1.什么时候可以使用盒装类型?
一方面它指出:
这是否意味着我可以拥有使用强类型盒装值类型的属性/方法,或者这只是规范中的一个遗漏?如果是这样,为什么我可以有属性而不是字段?
另一方面,即使在使用 MyStruct^
but seems to behave strangely with boxed primitive types( System.Int32^
) 的局部变量中,C++/CLI 似乎也支持装箱值类型。但我不确定哪一部分是 C++/CLI 编译器魔法(它可能使用标记的 Object
变量代替),哪一部分是由 CLR 处理的。
该规范进一步指出:
这似乎意味着强类型盒装值类型可以是类型的公共(public)接口(interface)的一部分。但不应用于 CLS 合规性(这是可以理解的,因为大多数语言不支持它们)。
那么在哪里可以使用强类型盒装值类型呢?为什么它可以用在那些地方,而不能用在其他地方?
2.拳击引用类型
该规范还提到了拳击引用类型:
装箱引用类型是空操作吗?允许装箱引用类型对于您不知道某个值是值还是引用类型的泛型参数很有用。因此,我假设为了与表示引用类型的泛型参数保持一致,允许对引用类型进行装箱。
3. 接口(interface)“在类型上定义”是什么意思?
最后,我在理解以下段落时遇到了问题:
“在类型上定义”的接口(interface)是什么意思?我的理解是,将值转换为接口(interface)/基类会装箱值,但您仍然可以使用受约束的虚拟调用调用未装箱的接口(interface)/类中定义的方法。 (带有约束前缀的 virtcall)
最佳答案
是的,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。否则这没有实际值(value)。
关于.net - 关于拳击的 CLR 规范,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7660605/