第一段代码:
object a = 10;
object b = a;
Console.WriteLine("b :"+ b);
a = 20;
Console.WriteLine("after a updateb :" + b);
我有这个代码片段它的答案是10和10(IMO!它应该是10和20,因为我使用的引用类型不是像 int 那样的值类型)。我希望如果变量变为更改,则应更新其分配的var。我知道使用它是不可能的:
第二个代码段
int a = 10;
int b = a;
Console.WriteLine("b :" + b);
a = 20;
Console.WriteLine("after a updateb :" + b);
因为上面的代码只会复制值。但是第一个代码片段有什么问题?我该怎么做
答案 0 :(得分:9)
两个片段都返回10.两者都是正确的。
在第一种情况下,a
和b
都持有对盒装实例10的引用。当您存储对a
的不同引用时,该盒装实例不会丢失。
在第二种情况下,b
包含a
值的副本。
如果您希望b
保留对a
的引用,您应该使用ref int
来声明该变量包含引用。这是C#7中的一个新功能:
int a = 10;
ref int b = ref a;
Console.WriteLine("b :" + b);
a = 20;
Console.WriteLine("after a updateb :" + b);
返回
b :10
after a updateb :20
答案 1 :(得分:4)
在第一个代码段中,a
属于object类型。因此分配
a = 20;
编译器将视为写入:
a = (object)20;
该分配意味着在堆上创建新对象,然后更新指针a
以指向此新对象。同时指针b
仍指向堆上的原始对象(仍包含10
)。
答案 2 :(得分:1)
这是因为当原始类型存储为Object
时,将发生装箱并将使用新的内存:
object a = 10; // 10 is boxed and reference holded in variable a
object b = a; // variable b also refers to the same reference which variable a is referring
Console.WriteLine("b :"+ b);
a = 20; // variable a now points to a new memory location with value 20
因此,当a
的内存引用更新为指向20
时,b
仍然指向a
之前引用的旧内存位置{ {1}}
因此a=20;
指的是b
所在的位置10
所指的位置,但a
现在指的是新位置。
您有两种价值类型,因此每个人都拥有自己的副本,因此在这种情况下,更改a
不会更改a
。
希望它能消除这种混乱。