C# 取消引用在幕后如何工作

问题描述 投票:0回答:1

这段代码来自名为“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;
...
}
c# pointers reference ref dereference
1个回答
1
投票

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

 属性,而不是创建新对象,并且在该方法完成后,可以在原始对象中看到此更改。

© www.soinside.com 2019 - 2024. All rights reserved.