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

C#行星对象未保留独立信息,均显示最后对象值求助

为什么所有行星对象都显示冥王星的属性值?

嘿,这个坑我见太多了——刚上手C#引用类型的开发者十有八九会踩!咱们先拆解问题根源,再给你解决办法。

问题出在「引用类型的实例化时机」

首先,你大概率是写出了类似这样的代码(我还原一下常见错误写法):

public class Planet
{
    public string Name { get; set; }
    public double Mass { get; set; }
}

// 错误写法:只创建了一个Planet实例
List<Planet> solarSystem = new List<Planet>();
Planet tempPlanet = new Planet(); // 这里只在内存里生成了一个行星对象

// 行星数据
var planetData = new[] {
    ("水星", 3.3011e23),
    ("金星", 4.8675e24),
    ("地球", 5.97237e24),
    // ... 省略其他行星
    ("冥王星", 1.30900e22)
};

foreach (var data in planetData)
{
    tempPlanet.Name = data.Item1;
    tempPlanet.Mass = data.Item2;
    solarSystem.Add(tempPlanet); // 每次加的都是同一个对象的引用!
}

// 输出时全是冥王星
foreach (var planet in solarSystem)
{
    Console.WriteLine($"{planet.Name}: {planet.Mass}");
}

核心原因:引用类型的「引用」特性

C#里的自定义类(比如你的Planet)属于引用类型——变量(比如tempPlanet)存储的不是对象本身,而是对象在内存中的「地址」。

上面的代码里,tempPlanet = new Planet()只执行了一次,意味着内存里只有一个Planet对象。循环里你只是不断修改这个对象的属性,然后把同一个地址反复添加到列表里。最后一次循环把这个对象改成了冥王星的属性,所以列表里所有元素指向的都是这个唯一的对象,自然输出全是冥王星的值。

怎么解决?每次循环创建新实例

把new Planet()放到循环内部,让每次迭代都在内存里生成一个全新的Planet对象:

List<Planet> solarSystem = new List<Planet>();
var planetData = new[] {
    ("水星", 3.3011e23),
    ("金星", 4.8675e24),
    ("地球", 5.97237e24),
    // ... 省略其他行星
    ("冥王星", 1.30900e22)
};

foreach (var data in planetData)
{
    // 每次循环都新建一个Planet实例
    Planet tempPlanet = new Planet();
    tempPlanet.Name = data.Item1;
    tempPlanet.Mass = data.Item2;
    solarSystem.Add(tempPlanet); // 现在添加的是不同对象的引用
}

// 现在就能正确输出每个行星的属性了
foreach (var planet in solarSystem)
{
    Console.WriteLine($"{planet.Name}: {planet.Mass}");
}

额外提一句:如果你的Planet是struct(值类型),就不会有这个问题,但自定义实体类一般都用class,所以一定要注意实例化的时机哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:51:16