gpt4 book ai didi

c# - 字符串是引用类型,但为什么它在赋值更新时作为值类型工作

转载 作者:太空狗 更新时间:2023-10-29 21:21:41 25 4
gpt4 key购买 nike

这是一个简单的代码片段,让我有点困惑:

string s1 = "abc";
string s2 = s1;
s2 = "123";
Debug.Log(s1 + ":" + s2);

调试结果为abc:123

那么为什么 s1 没有更新为 123,因为 s1 和 s2 包含相同的引用,如果一个变量更新它,第二个将自动更新。

最佳答案

这是对引用使用的常见误解。

s1 是一个引用类型,但它的内容是一个值。您可能认为所有变量都是值类型,但编译器处理它们的方式因值或引用类型而异。

    string s1 = "abc"; 

s1 等于存储“abc”的地址,比方说0x0000AAAA

    string s2 = s1; 

s2 指向与 s1 相同的地址,因此,它的值与 s1 相同。两者的值都是 0x000AAAA

    s2 = "123"; 

字符串是不可变的,这意味着你不能修改一个字符串,任何时候你分配一个新值或修改,你都在内存中的其他地方创建一个新字符串,而前一个字符串准备好进行 GC,如果需要的话(在我们的例子中不是实际上)。那时,s1 的值仍然是 0x0000AAAA,而 s2 的值是新的 0X0000BBBB。

    Debug.Log(s1 + ":" + s2);

由于两者指向的内容不同,所以打印的结果不同。

它只是一个引用类型,因为包含在变量中的值并不意味着按原样使用,而是意味着将指针发送到内存中存储实际对象的地址位置。

除非您使用 out/ref(C++ 中的 &),否则暗示要使用变量的值(地址),很可能用作参数。

请注意,此行为对于任何对象都是相同的,而不仅仅是字符串。

Dog dogA = new Dog();
Dog dogB = dogA;
dogA.name = "Wolfie"; // Affect both since we are dereferencing
dogA = new Dog(); // dogA is new object, dogB is still Wolfie

编辑:OP 需要对 ref/out 进行解释。

当你想改变一个对象时,你会想到以下几点:

void ChangeObject(GameObject objParam)
{
objParam = new GameObject("Eve");
}

void Start(){
GameObject obj = new GameObject("Adam");
ChangeObject(obj);
Debug.Log(obj.name); // Adam...hold on should be Eve (??!!)
}

ChangeObject 获取一个 GameObejct 作为参数,编译器将 obj (00000AAAA) 中包含的值复制到 objParam 上,并复制它,现在两者具有相同的值。

在方法内,objParam被赋予了新的值,与方法外的obj不再相关。 objParam 是方法的局部参数,在完成时被移除(游戏对象仍在场景中,但引用丢失)。

如果你想在方法中改变obj:

void ChangeObject(ref GameObject objParam)
{
objParam = new GameObject("Eve");
}

void Start(){
GameObject obj = new GameObject("Adam");
ChangeObject(ref obj);
Debug.Log(obj.name); // Yeah it is Eve !!!
}

这次传递的不是obj的值,而是obj的地址。所以 obj 可能包含 0x0000AAAA 但它自己的地址是 0x0000AABB,那么 objParam 的值现在是 0x0000AABB,改变 objParam 意味着改变存储在 0x0000AABB 的值。

out 和 ref 的工作原理相同,只是 out 需要在方法内赋值,而 ref 可以离开方法而不影响给定的参数。

关于c# - 字符串是引用类型,但为什么它在赋值更新时作为值类型工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36276619/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com