Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.net中,对象的装箱发生在什么级别?_C#_.net_Boxing - Fatal编程技术网

C# 在.net中,对象的装箱发生在什么级别?

C# 在.net中,对象的装箱发生在什么级别?,c#,.net,boxing,C#,.net,Boxing,如果我将一个对象(如列表)强制转换为对象),然后再次转换,那么所有字符串都会被强制转换,还是只转换为包含它们的列表 我认为编译器只需检查对象是否属于列表类型,然后再转换回列表,但我是在C中长大的,因此,我不能完全确定我编写的代码背后发生了什么。string是一种引用类型-string的实例永远不会被装箱 但是,如果您有一个列表,那么该列表是一个引用类型,因此这里也没有装箱int是一种值类型,如果将其强制转换为对象(隐式或显式),则可以将其装箱 装箱仅影响值类型-List是一个类,因此是引用类型,

如果我将一个对象(如
列表
)强制转换为
对象
),然后再次转换,那么所有字符串都会被强制转换,还是只转换为包含它们的列表


我认为编译器只需检查
对象
是否属于
列表
类型,然后再转换回
列表
,但我是在C中长大的,因此,我不能完全确定我编写的代码背后发生了什么。

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

但是,如果您有一个
列表
,那么该列表是一个引用类型,因此这里也没有装箱
int
是一种值类型,如果将其强制转换为对象(隐式或显式),则可以将其装箱

装箱仅影响值类型-
List
是一个类,因此是引用类型,更改泛型类型T不会影响实例是通过值还是通过引用传递


泛型集合有助于防止装箱,因为它允许读取/写入值类型,而无需将值类型装箱到
对象

当您将
列表
强制转换到
对象
时,实际上根本没有进行任何强制转换。您将一个引用分配给一些数据,分配给一个不太具体的引用。它包含的
字符串
对象也没有任何更改


另外,为了澄清,本案不涉及拳击。当创建对值类型(如
int
或某些
struct
)的引用时,通过将其赋值或以某种方式传递给
object
类型的变量,会发生装箱

如果要强制转换
列表
项,请执行以下操作:

List<string> list = new List<string>{"first", "second"};
List<object> objectsList = list.Cast<object>();
List List=新列表{“第一”、“第二”};
List objectsList=List.Cast();

另一方面,
string
是一种引用类型,因此当结构/值类型存储在该结构实现的对象或接口的类型位置时,它不能真正得到
装箱
取消装箱

装箱。在此场景中,
List
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

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


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

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

好的,那么值类型呢?是否需要将
列表
框起来?否,因为列表是参考类型。内容不需要装箱。int a=list[0]不是装箱,但列表是引用类型。只要不直接使用,就根本不需要装箱。值类型的集合可能会导致其内容被装箱(虽然适当的泛型类(如
List
)可以避免这种情况),但只要将项添加到集合中,就会发生这种情况。此外,装箱需要结构,而其他列表或字符串都不是结构,它们是类。这是否也意味着
列表
在性能方面与
列表
相同,因为它们都是引用类型?这不是创建泛型的原因吗?@ChandlerPelhams:如果你真的打算使用它,就不会。要将
对象
用作
字符串
,需要将其重新转换。这就是创建泛型的原因之一。当输入一个字符串时,它会为您保存一个ast。如果参数是类似于中的结构,它还可以为您节省装箱操作。遗憾的是,您的示例不是结构(字符串不是结构)。你要求一个具体的例子。