我要问的问题让我感到困惑,只是因为我正在深入研究一些 C# 细节。考虑以下代码:
public class Node
{
public int Data {get;set;}
}
var a = new Node() { Data = 1 }; // address in memory 0x600000
var b = new Node() { Data = 2 }; // address in memory 0x700000
var c = new Node() { Data = 3 }; // address in memory 0x800000
a = b; // variable a holds a reference to the memory location of b -> 0x700000
b = c; // variable b holds a reference to the memory location of c -> 0x800000
Run Code Online (Sandbox Code Playgroud)
如果我做
b.Data = 4;
Run Code Online (Sandbox Code Playgroud)
这是我的输出
Console.WriteLine(a.Data); //2
Console.WriteLine(b.Data); //4
Console.WriteLine(c.Data); //4
Run Code Online (Sandbox Code Playgroud)
在这里,我期望为所有三个变量打印出 4。为什么?因为,从代码的角度来看,a有一个对 的引用b,b有一个对 的引用c,因此a和c两者都有对完全相同的内存位置的引用 - 这是错误的。
最后的话或者我如何解释这一点:
a将 object 的地址作为值b,
b将 object 的地址作为值c
b和c位于内存中两个不同的位置,因此当您对 进行更改时b,当您通过变量访问它时,b或者c实际上您正在更改变量的值c(b和c指的是数据将在其中访问的相同内存地址空间)时, 和 将会可见被存储在)。当您通过这些访问值时,a即使在代码中您也不会看到对b. 实际上,这里根本没有改变,因此我们得到了变量指向的a值。b
我的理解正确还是你有更清晰的解释?
当你这样做时:
a = b;
Run Code Online (Sandbox Code Playgroud)
a现在指向b也指向的内存位置,但是当执行以下行时:
b = c;
Run Code Online (Sandbox Code Playgroud)
现在b和c都指向相同的内存位置,因此当我们更新 时,它会更改为 和也指向b的相同内存位置,但不会指向该内存位置,因此它不会像引用那样看到更改按值传递。bca
如果我们希望所有引用变量都反映更改,那么我们应该使用引用传递。您可以阅读有关按值传递和按引用传递之间的区别的更多信息,以获得更多理解。
请参阅以下内容以帮助理解,当b分配时c,它会与其原始内存位置断开连接,现在b两者c都引用公共内存位置,但不是a:
如果您将它们分配在单行上,则可以实现您期望的行为,例如:
a = b = c;
Run Code Online (Sandbox Code Playgroud)
现在,当您Data使用c变量更新时,它将反映所有 3 个变量。
请查看下图以了解本例中发生的情况:
| 归档时间: |
|
| 查看次数: |
109 次 |
| 最近记录: |