C#中Dictionary存储自定义类时不同实例数据异常共享问题
问题根因排查&解决方案
最高发原因:StorageList内部封装的List为静态字段
静态字段属于类级别,所有类实例共享同一份存储空间,哪怕你创建了多个不同的StorageList实例,内部操作的都是同一个List对象,自然会出现不同实例添加的元素都存在同一个列表里的现象。
错误代码示例
public class StorageList { // 错误声明:加了static修饰符,所有实例共享该列表 private static List<int> _storage = new List<int>(); public void AddItem(int value) { _storage.Add(value); } public List<int> GetList() { return _storage; } }
修复方案
去掉字段的static修饰符,改为实例级字段,每个StorageList实例初始化时都会创建独立的列表:
public class StorageList { // 正确声明:实例级字段,每个实例独有一份 private List<int> _storage = new List<int>(); public void AddItem(int value) { _storage.Add(value); } public List<int> GetList() { return _storage; } }
次常见原因:多个StorageList复用了同一个外部List实例
如果你的StorageList构造函数支持传入外部List初始化,你可能不小心给两个不同的StorageList实例传入了同一个List对象,此时就算StorageList本身是不同引用,内部操作的列表还是同一份。
错误代码示例
// 全局共用同一个List实例 var commonList = new List<int>(); var storage1 = new StorageList(commonList); var storage2 = new StorageList(commonList); dict.Add("idOne", storage1); dict.Add("idTwo", storage2);
修复方案
要么构造StorageList时每个实例都传入独立的List,要么在StorageList内部构造时对传入的List做拷贝:
public class StorageList { private List<int> _storage; public StorageList(List<int> inputList) { // 对传入的列表做拷贝,不直接复用外部实例 _storage = new List<int>(inputList); } }
快速验证方法
运行以下代码确认内部列表是否为同一引用:
var s1 = dict["idOne"]; var s2 = dict["idTwo"]; // 输出True说明两个实例内部的列表是同一个对象 Console.WriteLine(object.ReferenceEquals(s1.GetList(), s2.GetList()));
内容的提问来源于stack exchange,提问作者roccaforte
相关产品推荐
相关产品推荐

