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
相关产品推荐
相关产品推荐

