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

为何调用Console.WriteLine(foo)时结构体Foo的value值未持续递增?

为何值类型Foo的value在Console.WriteLine(foo)时没有递增?

我知道这看起来很简单,但我就是无法理解原因。以下是相关代码:

static void Main(string[] args)
{
    var foo = new Foo();
    Console.WriteLine(foo);
    Console.WriteLine(foo);
    object bar = foo;
    object qux = foo;
    object baz = bar;
    Console.WriteLine(baz);
    Console.WriteLine(bar);
    Console.WriteLine(baz);
    Console.WriteLine(qux);
}
struct Foo
{
    public int value;
    public override string ToString()
    {
        value++;
        return $"{value}";
    }
}

这段代码的输出为:1 1 1 2 3 1。我想知道为何执行Console.WriteLine(foo)时变量value的值没有递增。


原因解析

核心问题出在Foo是值类型(struct),值类型的传递逻辑和引用类型完全不同:

  • 调用Console.WriteLine(foo)时,该方法的参数是object类型,这会触发装箱操作:系统会创建一个新的object实例,把foo的当前值完整复制进去,然后调用这个装箱副本的ToString()方法。也就是说,每次调用Console.WriteLine(foo),修改的都是副本的value,原变量foo的value始终是初始的0,所以两次输出都是1。

  • 执行object bar = foo;时,同样触发装箱操作,把当前foo(value=0)的副本装箱为object实例,bar指向这个实例;object qux = foo;同理,生成另一个独立的装箱副本。而object baz = bar;是引用赋值,因为bar是引用类型(装箱后的object),所以baz和bar指向同一个装箱后的Foo实例。

  • 后续的输出调用:

    • Console.WriteLine(baz):调用共享实例的ToString(),value从0变为1,输出1;
    • Console.WriteLine(bar):同一个实例,value变为2,输出2;
    • Console.WriteLine(baz):同一个实例,value变为3,输出3;
    • Console.WriteLine(qux):调用独立的装箱副本,value从0变为1,输出1。

这就完全对应了代码的输出结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 01:00:54