Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.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# 取消装箱不会创建值的副本。是这样吗?_C#_.net - Fatal编程技术网

C# 取消装箱不会创建值的副本。是这样吗?

C# 取消装箱不会创建值的副本。是这样吗?,c#,.net,C#,.net,我正在读微软的教室培训材料。我读了以下内容 拆箱 拆箱是拳击的反面。它是将引用类型显式转换为 值类型。取消装箱检索对对象中包含的值类型的引用。 取消装箱操作涉及检查对象实例以确保对象 实例是给定值类型的装箱值。然后,实例中的值为 复制到值类型变量中 ** 取消装箱返回一个指向装箱对象内数据的指针,并且不创建数据的副本。 ** 我不太明白我强调的那句话。它表示,当取消装箱对象时,它不会创建副本,只返回一个指针。如果这是真的,那么将在堆中分配一个值类型变量,对吗 嗯,这是真的,但不是全部 取消装箱本

我正在读微软的教室培训材料。我读了以下内容

拆箱 拆箱是拳击的反面。它是将引用类型显式转换为 值类型。取消装箱检索对对象中包含的值类型的引用。 取消装箱操作涉及检查对象实例以确保对象 实例是给定值类型的装箱值。然后,实例中的值为 复制到值类型变量中

**

取消装箱返回一个指向装箱对象内数据的指针,并且不创建数据的副本。

**

我不太明白我强调的那句话。它表示,当取消装箱对象时,它不会创建副本,只返回一个指针。如果这是真的,那么将在堆中分配一个值类型变量,对吗


嗯,这是真的,但不是全部

取消装箱本身只返回一个指向数据的指针,但不能使用该指针访问C#中的数据。在C#中取消绑定值时,总是将其复制到某个位置

例如:

object o = 42; //box
int i = (int)o; //unbox

拆箱iself获取指向对象
o
中的值
42
的指针,然后将该值复制到变量
i

,除了Guffa所说的,这里还有一些附加信息:

  • 您引用的文本中描述的“取消装箱”操作描述了
    unbox
    CIL指令。CIL标准对
    unbox
    有如下说明:

    不同于
    ,它是 在中使用的值类型的副本 对象,
    unbox
    不需要复制 对象中的值类型。 通常,它只计算 指定的值类型的地址 盒子里已经有了 反对

  • 在C#中使用的取消装箱转换不会编译为
    unbox
    它们会编译为另一条名为
    unbox的指令。任何

    […]
    unbox。任何
    指令都提取其中包含的值 obj(类型为
    O
    )。(它相当于
    unbox
    后跟
    ldobj

    在英语中,这意味着
    unbox。任何
    都会执行一个unbox操作(
    unbox
    )-将指针推送到计算堆栈上,然后执行复制操作(
    ldobj
    ),将指针转换为值类型中包含的实际值,并将其推送到计算堆栈上

    为完整起见,以下是对ldobj的描述:

    ldobj
    指令复制一个值 到求值堆栈。[…]src是非托管指针 (本机int)或托管指针 (&). [……]

    [理由:联合国
    ldobj
    指令可用于传递 作为参数的值类型。结束 [理由]


据我所知,C#编译器从不使用
unbox
ldobj
,它总是使用
unbox.any
进行unboxing,并使用
ldind.
取消引用(例如
ref
/
out
参数).

是否有指向未绑定值的指针可以直接使用而无需复制值的地方?@RAM:我不这么认为,至少不容易。也许您可以使用
fixed
将对象固定在内存中,并获取指向该值的指针,但这比仅复制该值要复杂得多。被装箱的值很小,因此没有真正的理由避免复制它。@colinfang:取消装箱值会得到一个指向对象中的值的指针,它不会复制该值,直到您实际将其用于某个目的。取消绑定结构并在其中使用字段将从已装箱的结构中复制该字段的值。解释非常清楚。从你和Guffa给出的答案中,我清楚地理解了拆箱。谢谢你的解释和时间记忆