我试图验证自己对C#/.NET/CLR如何处理值类型和引用类型的理解。我已经读了很多矛盾的解释,仍然不太清楚。
这是我今天的理解,请纠正我如果我的假设是错误的。
像int等值类型存在于栈上,引用类型存在于托管堆上,但是如果一个引用类型有一个类型为double的实例变量,它将与其对象一起存在于堆上。
第二部分是我最困惑的。
考虑一个简单的名为Person的类。
Person有一个名为Name的属性。
假设我在另一个类中创建了Person的一个实例,我们称之为UselessUtilityClass。
考虑以下代码:
class UselessUtilityClass
{
void AppendWithUnderScore(Person p)
{
p.Name = p.Name + "_";
}
}
然后我们在某个地方执行:
Person p = new Person();
p.Name = "Priest";
UselessUtilityClass u = new UselessUtilityClass();
u.AppendWithUnderScore(p);
Person是一个引用类型,当传递给UselessUtilityClass时 - 这就是我发疯的地方... 实例化Person的变量p是按值传递的,这意味着当我写p.Name时,我会看到"Priest_"。
然后,如果我写了:
Person p2 = p;
我执行以下操作:
p2.Name = "Not a Priest";
然后像下面这样写 p 的名称,就可以得到 "Not a Priest"。
Console.WriteLine(p.Name) // will print "Not a Priest"
这是因为它们是引用类型并指向内存中相同的地址。我的理解正确吗?
我认为人们说“所有.NET对象都是按引用传递”的时候存在一些误解,这与我的想法不符。我可能错了,这就是为什么我来到Stackers的原因。