关于拳击的 CLR 规范

发布于 2024-12-08 10:17:42 字数 1943 浏览 1 评论 0原文

我目前正在阅读 CLR 规范 。我在理解“I 8.2.4 值的装箱和拆箱”部分时遇到了一些困难。

1.什么时候可以使用盒装类型?

一方面它指出:

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

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

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

另一方面,即使在使用 MyStruct^ 的局部变量中,C++/CLI 似乎也支持装箱值类型 但对于盒装原始类型(System.Int32^)来说似乎表现得很奇怪。但我不确定其中哪一部分是 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)

I'm currently reading the CLR specification. I have a bit of trouble understanding section "I 8.2.4 Boxing and unboxing of values".

1. When can boxed types be used?

On the one hand it states:

For every value type, the CTS defines a corresponding reference type called the boxed type. [...] The representation of a value of a
boxed type (a boxed value) is a location where a value of the value type can be stored. A boxed type is an
object type and a boxed value is an object.

A boxed type cannot be directly referred to by name, therefore no field or local variable can be given a boxed
type.
The closest named base class to a boxed enumerated value type is System.Enum; for all other value types
it is System.ValueType. Fields typed System.ValueType can only contain the null value or an instance of a
boxed value type. Locals typed System.Enum can only contain the null value or an instance of a boxed
enumeration type.

Does this mean I can have properties/methods which use strongly typed boxed value types, or is this just an omission in the spec? If so, why can I have properties but not fields?

On the other hand C++/CLI seems to support boxed value types even in local variables using MyStruct^ but seems to behave strangely with boxed primitive types(System.Int32^). But I'm not sure which part of that is C++/CLI compiler magic (it might use tagged Object variables instead), and which part is handles by the CLR.

The spec further states:

CLS Rule 3: Boxed value types are not CLS-compliant.
[Note: In lieu of boxed types, use System.Object, System.ValueType, or System.Enum, as appropriate.

This seems to imply that strongly typed boxed value types can be part of the public interface of a type. But should not be used for CLS compliance(which is understandable since most languages don't support them).

So where can strongly typed boxed value type be used? And why can it be used in those places, but not others?

2. Boxing reference types

The spec also mentions boxing reference types:

A type is boxable if it is one of the following:

[...]

  • A reference type (including classes, arrays, delegates, and instantiations of generic classes) excluding
    managed pointers/byrefs (§8.2.1.1)

  • A generic parameter (to a generic type definition, or a generic method definition) [Note: Boxing and
    unboxing of generic arguments adds performance overhead to a CLI implementation. The constrained.
    prefix can improve performance during virtual dispatch to a method defined by a value type, by avoiding
    boxing the value type. end note]

Is boxing a reference type a no-op? Allowing boxing reference types is useful on generic parameters where you don't know if something is a value or reference type. So I assume boxing a reference type is allowed for consistency with generic parameters that represent a reference type.

3. What is the meaning of an interface being "defined on a type"?

And finally I have problems understanding the following paragraph:

Interfaces and inheritance are defined only on reference types. Thus, while a value type definition (§8.9.7) can
specify both interfaces that shall be implemented by the value type and the class (System.ValueType or
System.Enum) from which it inherits, these apply only to boxed values.

What is the meaning of an interface being "defined on a type"? My understanding is that casting to interfaces/base classes boxes the value, but you can still call methods defined in such an interface/class on the unboxed using constrained virtual calls. (virtcall with constraint prefix)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦毁影碎の 2024-12-15 10:17:42

是的,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 即可。否则这没有实际价值。

Yes, the C++/CLI language allows declaring strongly typed boxed value types:

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

It observes the CLI spec however, the boxedInt field is typed ValueType in the metadata. It remembers, and checks, the boxed type with modOpt attributes:

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

The exact same thing is possible in C#, minus the compiler checking that only int values are assigned to the field. Simply declare the field as ValueType. This has otherwise no practical value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文