You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在按值传递对象的框架中更新引用类型的引用?

解决C#中类间对象引用更新的问题

我明白你熬夜调试的痛苦——这种引用传递的问题很容易钻牛角尖。咱们先直接说解决方案,再拆解原因。

快速修复:正确使用ref传递你的目标引用

你写的SwapPersonTwo方法其实本身是可以工作的,但你调用的时候传错了参数!你现在传的是ref charlie,但我们需要修改的是Main里的person变量的引用,所以应该传ref person。

修改Main里的调用代码:

// 替换原来的注释代码,使用正确的参数
foo.SwapPersonTwo(ref person);

同时可以把SwapPersonTwo的方法签名优化得更清晰:

public void SwapPersonTwo(ref Person targetPerson)
{
    // 如果你想直接在方法里创建新对象:
    targetPerson = new Person { FirstName = "Charlie", LastName = "Chaplin", Age = 130 };
    // 或者如果你想传入外部创建好的charlie,就改成:
    // targetPerson = charlie;
}

这样运行后,你就能看到Main里的person引用被成功替换成Charlie的对象了。

为什么你的其他方法都失败了?

咱们逐个分析:

  • SwapPersonOne:C#中引用类型参数默认是按值传递引用——你传递的是charlie引用的副本,方法里修改的是Foo类内部的person变量(它只是Main里person的一个副本引用),所以Main里的原始引用完全不受影响。
  • SwapPersonThree/SwapPersonFour:这两个方法都是在修改Foo类自己的person成员变量,和Main里的person变量没有任何关系——它们只是一开始指向同一个对象,但变量本身是独立的。修改Foo内部的引用,不会同步到Main里的变量。

其他可行方案

如果你不想用ref,还有两种常见方式:

方案1:让Foo暴露Person属性,在Main里同步更新

给Foo类添加一个公共属性:

public Person CurrentPerson
{
    get => person;
    set => person = value;
}

然后在Main里:

foo.CurrentPerson = charlie;
person = foo.CurrentPerson; // 同步Main里的引用

方案2:让Foo返回新的Person对象,在Main里赋值

修改Foo的方法:

public Person SwapPersonReturn()
{
    person = new Person { FirstName = "Charlie", LastName = "Chaplin", Age = 130 };
    return person;
}

然后Main里:

person = foo.SwapPersonReturn();

核心概念梳理

记住这个关键点:引用类型的变量存储的是对象在堆上的地址。当你按值传递引用类型参数时,传递的是这个地址的副本——所以方法里修改副本的地址(比如赋值新对象),不会改变原始变量的地址。只有用ref/out传递时,才会传递变量本身的引用,方法里的修改才会影响原始变量。

内容的提问来源于stack exchange,提问作者Nick W.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:38:43