为何重新赋值变量无法更新C#数组元素?
为什么修改引用变量无法更新数组元素,而直接修改数组索引可以?
先看你给出的两个代码示例,核心问题出在C#引用类型变量的本质上——引用变量存储的是对象在堆内存中的地址,而非对象本身。我们逐个拆解:
第一个示例的执行逻辑
string anElement = "World"; string[] col = new string[2] { "Hello", anElement }; anElement = "Jupiter"; Array.ForEach(col, Console.WriteLine);
anElement = "World":anElement变量保存了字符串"World"在堆上的内存地址。- 创建数组
col时,第二个元素复制的是anElement里的地址,所以数组的第二个元素和anElement此刻指向同一个"World"对象。 anElement = "Jupiter":这一步是给anElement变量重新赋值了一个新地址(指向新的字符串"Jupiter"),但数组col的第二个元素依然保存着原来"World"的地址,所以输出还是World。
第二个示例的逻辑完全一致
string[] col = new string[2] { "Hello", "World" }; string elementToUpdate = col[1]; elementToUpdate = "Jupiter"; Array.ForEach(col, Console.WriteLine);
elementToUpdate = col[1]:elementToUpdate拿到的是col[1]里存储的"World"的地址。elementToUpdate = "Jupiter":同样是给elementToUpdate换了个新的地址指向"Jupiter",但col[1]里的地址完全没被修改,所以数组输出不变。
直接修改数组索引为什么有效
当执行col[1] = "Jupiter"时,是直接把数组的第二个元素存储的地址替换成了"Jupiter"的地址,数组里的引用指向被直接修改,所以输出会变成Jupiter。
补充:和string不可变性无关
很多人会误以为是string的不可变性导致的,但其实换成任意引用类型结果都一样。比如自定义类:
class Person { public string Name { get; set; } } Person p = new Person { Name = "Alice" }; Person[] arr = new Person[] { p }; // 重新赋值p的指向 p = new Person { Name = "Bob" }; Console.WriteLine(arr[0].Name); // 输出Alice,因为arr[0]还是原来的Person对象地址 // 但如果修改对象的内部属性,就会同步 p = arr[0]; p.Name = "Charlie"; Console.WriteLine(arr[0].Name); // 输出Charlie,因为p和arr[0]指向同一个对象,修改对象内容会同步
内容的提问来源于stack exchange,提问作者faridOP
相关产品推荐
相关产品推荐

