如果我有一个List<string>
这样的对象,我将其转换为object
,然后再返回,是否所有字符串都会被转换,或者仅包含它们的列表?
我认为编译器只需检查object
是否为List<string>
类型,然后再转回List<string>
但我在C#中长大,所以我'我不完全确定我写的代码背后发生了什么。
答案 0 :(得分:6)
当你将List<string>
投射到object
时,你根本就没有做任何投射。您将一些数据的引用分配给一个不太具体的引用。它包含的string
个对象也没有改变。
此外,澄清一下,在这种情况下没有拳击。当您创建对int
或某些struct
等值类型的引用时,通过分配或以某种方式将其传递给object
类型的变量,就会发生拳击。
答案 1 :(得分:3)
当结构/值类型存储在键入到对象的位置或该结构实现的接口时,就会发生拳击。在这种情况下,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
答案 2 :(得分:2)
string
是一种引用类型 - string
的实例永远不会被装箱。
如果你有一个List<int>
,那么List就是一个引用类型,所以这里也没有装箱。 int
是一个值类型,如果它被强制转换为对象(隐式或显式),它可以被装箱。
Boxing只影响值类型 - List<T>
是一个类,因此是一个引用类型,更改泛型类型T不会影响实例是按值传递还是通过引用传递。
通用集合有助于防止装箱,因为它可以读取/写入值类型,而不会被装箱到object
。
答案 3 :(得分:1)
对于每种值类型,都有一个具有相同名称的相应对象类型,该类型派生自ValueType。每当需要创建给定类型的存储位置(字段,变量或参数)时,系统将分配空间来存储堆引用(如果类型不是从ValueType派生的),所有类型的字段(如果它是'struct'),或者是持有类型值的位。当尝试将值类型的实例存储到堆引用中时,会发生Boxing。当尝试使用堆引用时,就会发生取消装箱,就好像它是值类型一样。请注意,在某些上下文中,取消装箱会将装箱对象的内容复制到新的存储位置,但在其他上下文中,它会将装箱的实例视为存储位置。这种语义并不总是很清楚,这是一些人讨厌可变结构的原因之一。在实践中,如果避免使用语义变得模糊的使用场景,可变结构就可以了,甚至不可变结构也会受到同样模糊语义的影响。
答案 4 :(得分:0)
只会投放List<string>
。
如果你想要投射List<string>
项,请执行以下操作:
List<string> list = new List<string>{"first", "second"};
List<object> objectsList = list.Cast<object>();
P.S。 string
是一种引用类型,因此无法真正获得boxed
和unboxed
答案 5 :(得分:0)
Boxing和Unboxing是适用于值类型而非参考类型的操作。
不是这样,它只是一个简单的演员。