net中对象的装箱发生在什么级别
本文关键字:在什么 对象 net | 更新日期: 2023-09-27 18:20:04
如果我有一个像List<string>
这样的对象,我将其转换为object
,然后再返回,那么所有字符串都会被转换还是只转换包含它们的列表?
我认为编译器只需要检查object
是否属于List<string>
类型,然后再转换回List<string>
,但我是在C#中长大的,所以我不完全确定我编写的代码背后发生了什么。
当您将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
是一个引用类型,因此它不能真正获得boxed
和unboxed