3

我怀疑这背后有一些我完全没有注意到的真正根本的东西。我可以写

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

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

但是,我可以写

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

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

4

5 回答 5

6

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

int b = a;

您正在将 a 的值复制到 b。

但是,还有一个“参考”类型。这只会复制对变量的引用- 换句话说,它会获得变量的一种句柄,因此当对该变量进行更改时,它们会在两个地方反映出来。

值类型包括structs 和所有原语 - 整数、双精度、字符等,字符串除外。引用类型就是其他一切。

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

于 2013-10-09T19:06:30.547 回答
2

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

虽然我认为这最终会成为一个重复的问题,但我很抱歉没有在链接上进一步阐述。

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

值类型的行为与您的第一个示例中一样,存储其值所需的内存分配在堆栈上,堆栈在包含对象的范围内生存和死亡。

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

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

于 2013-10-09T19:05:47.947 回答
2

.NET 中有两种类型,值类型和引用类型。int 是值类型,double[] 是数组,是引用类型。

您的第一个a = b分配 b (它只保存值 5)到a。在您的第二个示例b中,引用内存中的数组,并且a = b简单地指向a同一个数组。

于 2013-10-09T19:07:30.743 回答
1

标准数组行为。

如果您使用简单=运算符,将传递一个引用,然后您操作原始对象。

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

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

当您现在更改 b 时,将不会更改 a。

警告:

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

于 2013-10-09T19:07:18.940 回答
1

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

于 2013-10-09T19:06:28.780 回答