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

C#中引用类型所持引用类型的内存存储位置问询

C#内存分配分析(针对你的代码)

首先是你的代码:

public class Wallet
{
    private int _money;

    public Wallet(int money)
    {
        _money = money;
    }
}

public class Person
{
    private string _name;
    private Wallet _wallet;

    public Person(string name)
    {
        _wallet = new Wallet(0);
        _name = name;
    }
}

class TestClass
{
    static void Main(string[] args)
    {
        var person = new Person("Toto");
    }
}

你的理解验证

  • 第1点正确:person是Main方法里的局部引用变量,存储在栈上,指向堆上的Person实例。
  • 第2点补充:Person的成员_name和_wallet是堆上Person实例的一部分,它们本身是引用类型的引用(而非实例),这两个引用存储在堆上,分别指向对应的字符串实例和Wallet实例。
  • 第3点正确:_money是Wallet类的值类型成员,Wallet实例在堆上,所以_money嵌入在堆上的Wallet实例中,存储在堆上。

你的疑惑解答

你关于“_wallet的引用存储在栈上”的理解是错误的。_wallet是Person类的成员字段,属于堆上Person实例的一部分,所以这个引用本身存在堆上,它指向堆上的Wallet实例。

完整内存分配流程梳理

  1. 执行new Person("Toto")时,堆上创建Person实例,实例包含_name(string引用)和_wallet(Wallet引用)两个字段,均存储在堆上。
  2. 执行_wallet = new Wallet(0)时,堆上创建Wallet实例,_money作为值类型嵌入该实例中;随后将Wallet实例的地址赋值给Person实例里的_wallet引用(堆上的引用)。
  3. 字符串"Toto"是引用类型实例,存储在堆上,Person实例的_name引用指向该字符串实例。
  4. Main方法里的person局部引用变量存储在栈上,指向堆上的Person实例。

一句话总结

栈上仅存在Main方法的person引用变量;堆上包含Person实例(含两个引用字段)、Wallet实例(含_money值)、字符串"Toto"实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 11:20:07