这段代码来自名为“Pro C# with .NET 6”的书,我想知道当对引用(ref Person p)的引用传递给该方法时幕后会发生什么。例如,当我们执行 p.personAge = 555; 时取消引用是否在幕后发生两次,首先获取 p 指向的变量,然后获取 p 指向的变量包含的值?抱歉,如果问题有点令人困惑,但总的来说,我想知道 C# 中的取消引用是如何工作的,在这种情况下,我们是否有编译器自动发生的两种方式取消引用?
static void SendAPersonByReference(ref Person p)
{
// Change some data of "p".
p.personAge = 555;
...
}
这段代码中也发生取消引用吗?
static void SendAPersonByReference(Person p)
{
// Change some data of "p".
p.personAge = 555;
...
}
ref
仅在您分配或更改变量本身时发挥作用,并且p.personAge = 555;
语句在任何一个示例中都不会这样做。是的,这里确实发生了赋值,但要等到您第一次检索对象然后查找该对象上的 personAge
属性之后,这 才会发生,而不需要 ref
。
理解差异的更好示例如下(假设 Person 是引用类型(类)而不是值类型(结构)):
static void SendAPerson(Person p)
{
p = new Person();
p.personAge = 555;
}
static void SendAPersonByReference(ref Person p)
{
p = new Person();
p.personAge = 555;
}
static void SendAPerson2(Person p)
{
p.personAge = 555;
}
现在有了这些新示例,我们需要考虑调用这些方法的代码中发生的情况,而不是方法本身。
使用第一个(普通)方法,用于调用此方法的原始 Person 变量没有任何变化。一旦该方法结束,该方法中创建的新对象就符合车库收集的条件,并且该方法中设置的 555
值将丢失。使用第二种(参考)方法,我们
替换了原始变量的内容。现在它保存了我们的新对象,并且 555
属性中包含
personAge
值。那里的任何对象现在都有资格进行垃圾回收(假设没有其他现有引用)。使用第三种(也是普通)方法,我们更改所提供对象上的
personAge
属性,而不是创建新对象,并且在该方法完成后,可以在原始对象中看到此更改。