C# = 意味着 2 种不同的东西

本文关键字:意味着 | 更新日期: 2023-09-27 18:34:34

我怀疑这背后有一些我完全忘记的基本内容。我会写

int b = 5;
int a = b;
a = 2; 

据我所知,这给了我两个独立的变量。最初,a 设置为 5,但随后我可以在不更改 b 的情况下将 a 更改为 2

但是,我可以写

double[] b = { 1, 2, 3, 4};
double[] a = b; 
a[2] = 9; 

现在,似乎我没有 2 个单独的变量,而是对同一实体的 2 个引用。更改 a[2] 现在更改 b[2]。这是怎么回事?

C# = 意味着 2 种不同的东西

C# 中有两种类型的变量。 第一个称为"值"类型。 当您为其赋值时,该值将复制到该位置,因此当您写入时

int b = a;

您正在 a 的值复制到 b。

但是,还有一个"引用"类型。 这仅复制对变量的引用 - 换句话说,它获得了变量的某种句柄,因此当对该变量进行更改时,它们会反映在两个位置。

值类型包括 struct s 和除字符串之外的所有基元 - 整数、双精度、字符等。 引用类型是其他所有内容。

一些评论者已经提供了很好的链接,所以我不会在这里添加任何链接。

.NET 中有两种类型:值类型和引用类型。Int 是一个值类型,double[] 是一个数组,它是一个引用类型。

您的第一个a = b将 b(仅保存值 5(分配给 a 。在第二个示例中,b在内存中保存对数组的引用,而a = b仅指向a指向同一数组。

在 C# 数组中是引用类型。 看到这里

虽然我认为这最终会是一个重复的问题,但我为没有进一步阐述链接而道歉。

在 C# 中,您有值类型和引用类型。 所有数组(即使它们是值类型的数组(都是引用类型。

值类型的行为与第一个示例中的行为类似,存储其值所需的内存在堆栈上分配,该堆栈随包含对象的作用域而生死。

引用类型仅存储指向堆上分配内存的位置的指针,并且它一直存在,直到垃圾回收器确定没有任何东西正在使用它并且可以清理它。 因此,如果将一个引用类型分配给另一个引用类型,则它们是具有不同名称的同一对象。

这当然过于简单化了,但是您可以在我的回答链接或任何针对同一主题的精彩SO问题中获得更多信息。

在第一个示例中,int 是一种值类型,每个值类型都被分配了一个内存位置。在第二个示例中,数组是复杂数据类型或引用类型,因此 get 分配为指针。

标准数组行为。

如果使用简单=运算符,则会传递引用,然后操作原始对象。

要防止这种行为,请使用内置函数.CopyTo()Array.Clone()

a.CopyTo(b, 0)
b = a.Clone();

当您现在更改 B 时,不会更改 A。

谨慎:

只有在确保 b 可以包含 a 的所有元素(b.Length>= a.Length(后才使用此函数,否则将抛出超出范围的索引异常