net中对象的装箱发生在什么级别

本文关键字:在什么 对象 net | 更新日期: 2023-09-27 18:20:04

如果我有一个像List<string>这样的对象,我将其转换为object,然后再返回,那么所有字符串都会被转换还是只转换包含它们的列表?

我认为编译器只需要检查object是否属于List<string>类型,然后再转换回List<string>,但我是在C#中长大的,所以我不完全确定我编写的代码背后发生了什么。

net中对象的装箱发生在什么级别

当您将List<string>强制转换为object时,实际上根本没有执行任何强制转换。您将一个引用指定给某些数据,指定给一个不太具体的引用。它包含的string对象也根本没有更改。


此外,需要澄清的是,本案不涉及拳击。当您通过将值类型(如int或某个struct)赋值或以某种方式将其传递给object类型的变量来创建对该值类型的引用时,就会发生装箱。

当一个结构/值类型存储在一个类型为对象或该结构实现的接口的位置时,就会发生装箱。在这种情况下,List<string>string都是引用类型,因此不会发生装箱。

struct S1 : IComparable {
  ...
}
S1 local = new S1();  // No box. 
object obj = local;   // Box S1 instance into object
IComparable comp = local;  // Box S1 instance into IComparable
obj = "hello";  // String is a reference type, no boxing

string是一个引用类型-string的实例永远不会被装箱。

但是,如果您有一个List<int>,那么List是一个引用类型,所以这里也不会有装箱。int是一种值类型,如果它被强制转换为对象(隐式或显式),则可以将其装箱。

装箱只影响值类型-List<T>是一个类,因此是一个引用类型,更改泛型类型T不会影响实例是按值传递还是按引用传递。

泛型集合有助于防止装箱,因为它允许在不装箱到object的情况下读取/写入值类型。

对于每个值类型,都有一个相应的同名对象类型,该对象类型是从ValueType派生的。每当需要创建给定类型的存储位置(字段、变量或参数)时,系统都会分配空间来存储堆引用(如果该类型不是从ValueType派生的)、该类型的所有字段(如果它是"struct")或保存类型值的位。当试图将值类型的实例存储到堆引用中时,就会发生装箱。当试图将堆引用当作值类型来使用时,就会发生取消装箱。请注意,在某些上下文中,取消装箱会将装箱对象的内容复制到新的存储位置,但在其他上下文中,它会将装箱实例视为存储位置。它的语义并不总是清晰的,这也是一些人讨厌可变结构的原因之一。在实践中,如果可以避免语义模糊的使用场景,那么可变结构是可以的,即使是不可变结构也可能遭受同样模糊的语义。

装箱和取消装箱是应用于值类型而非引用类型的操作。

不是这样,这只是一个简单的演员阵容。

只有List<string>会被广播。

如果你想铸造List<string>项目,请执行以下操作:

List<string> list = new List<string>{"first", "second"};
List<object> objectsList = list.Cast<object>();

p.S.string是一个引用类型,因此它不能真正获得boxedunboxed