繁体   English   中英

C#值和引用类型

[英]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 ------------|

这就是为什么当你做出的分配anull ,你不影响价值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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM