[英]C# Value and Reference types
请参阅下面提到的以下代码行:
byte[] a = { 1, 2, 3, 4 };
byte[] b = a; // b will have all values of a.
a = null;
在C#中, byte[]
是一个引用类型。 现在,如果第3行中的a = null
,那么为什么b
不是null,因为它是引用类型。 如果我们检查b
它仍然拥有的所有值a
。
首先,在内存中的某处创建一个数组,例如从地址1000
开始。 a
是引用,它不包含数组,它包含地址1000
。 b
还包含此地址。 在第3行中,您将a
更改为指向null
,但b
仍然指向地址1000
中的数组。
您编辑了引用( a
),但未编辑它引用的对象( {1,2,3,4}
)。
这实际上是参考类型的工作原理。
正如你所说, byte[]
是一个像所有其他数组一样的引用类型。 让我们逐行分析你的样本;
byte[] a = { 1, 2, 3, 4 };
- >你在内存中创建了一个字节数组, a
是一个引用该数组。
byte[] b = a;
- >你b
正在引用与同一个对象a
是{ 1, 2, 3, 4 }
但它们是不同的引用 。
a = null;
- >你的a
没有引用内存中的任何地方,但这不会影响b
。
您的问题假设您在完成作业时:
byte[] b = a;
并且您正在制作某种图形关联,如下所示:
b -> a -> { 1, 2, 3, 4 }
当你将a
赋值为null
,会影响b
的值,因为:
b -> a -> null
但这不是复制引用的工作方式。 当您复制引用,你真的做了引用的副本 a
了,就像这样:
a ----> { 1, 2, 3, 4 }
^
b ------------|
这就是为什么当你做出的分配a
到null
,你不影响价值b
,只是a
:
a ----> null { 1, 2, 3, 4 }
^
b ------------------------|
你正在使b
指向包含byte
数组的内存地址。 然后事后 ,你这是a
指向null
。 b
保持不变。
引用类型变量指向一个值。 将一个ref类型变量分配给另一个时,将对其值的引用复制到变量本身。 这就是为什么b
仍然指向一个值表。
当类型是值类型时,意味着此类型的变量存储实际数据。 当类型是引用类型时,意味着此类型的变量存储对实际数据的引用。
在这两种情况下,从一个变量到另一个变量的赋值都会复制变量的内容。 对于值类型,这意味着将值从一个变量复制到另一个变量,复制实际数据,从而创建新对象。 对于引用类型,这意味着引用从一个变量复制到另一个变量,复制引用但保留实际数据。 要强调:不复制对象,但引用是 。 引用的两个副本是独立的,即使很容易观察到它们在取消引用时指向同一个对象。
通过这些,您可以很容易地看到从一个变量到另一个变量的赋值复制了对字节数组的引用,因此您对字节数组有两个引用。 之后,当您为其中一个变量赋值null时,您正在复制对它的空引用,将原始引用(存储在该变量中)覆盖到字节数组。 所以,现在你没有对字节数组的两个引用,但只有一个引用 - 对象是相同的,但对它的引用是独立的。
(类似地,如果将字节数组重新分配给空变量,则并不意味着程序中指向null的所有变量都将指向字节数组 - 只指向您指定的字节数组。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.