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

关于C#中引用类型参数传递行为的困惑及代码疑问

为什么两段C#代码的输出结果不同?

先看你给出的两段代码及对应结果:

第一段代码

public class TestClass
{
    public int x;
    public int y;

    public TestClass(int xx, int yy)
    {
        this.x = xx;
        this.y = yy;
    }
}

void tfn(TestClass a)
{
    a = new TestClass(3, 4);
}

tfn(c);
Console.WriteLine($"c.x: {c.x}.");

运行结果:c.x: 1.

第二段代码

void tfn(TestClass a)
{
    TestClass b = a;
    b.x = 3;
}

tfn(c);
Console.WriteLine($"c.x: {c.x}");

运行结果:c.x: 3.

核心概念澄清

C#里所有参数传递都是按值传递,这是理解差异的关键。对于自定义类这类引用类型,变量存储的是对象在堆内存中的地址(即"引用")。当你把引用类型变量作为参数传入方法时,传递的是这个引用的副本——不是对象本身,也不是原变量的引用。

第一段代码分析

假设调用tfn(c)前,c是new TestClass(1, 2),此时c保存着指向该对象的内存地址(比如0x123):

  • 调用tfn(c)时,参数a会得到c中引用的副本,也就是a也指向0x123对应的对象。
  • 在tfn方法里执行a = new TestClass(3, 4),这是给局部变量a重新赋值,让它指向一个新创建的对象(内存地址比如0x456)。
  • 这个操作只修改了方法内部的a变量,完全不影响外部的c——c依然指向原来0x123的对象,所以输出c.x: 1。

第二段代码分析

同样,调用tfn(c)前c指向0x123的对象:

  • 调用tfn(c)时,参数a得到c引用的副本,同样指向0x123的对象。
  • TestClass b = a; 让b也保存这个引用,所以b、a、c都指向同一个堆上的对象。
  • b.x = 3; 是通过引用修改了堆上对象的x属性,这个修改直接作用于对象本身,而非变量。
  • 外部的c依然指向这个对象,所以输出时会看到修改后的x值3。

总结差异

  • 第一段代码是修改参数变量的引用指向:仅改变方法内局部变量的指向,和外部变量无关。
  • 第二段代码是通过引用修改对象的内部数据:所有指向该对象的变量都会感知到这个变化。

内容的提问来源于stack exchange,提问作者user8677843

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 00:33:34