泛型方法无法同步Dictionary修改至原对象的问题求助
泛型方法中字典参数无法同步更新的解决办法
你原本处理Apple数据加载的逻辑是这样的:
public void LoadApples(IEnumerable<Apple> apples) { _apples.Clear(); //_apples = List<Apple> _apples.AddRange(apples); ApplesId = _apples.ToDictionary(keySelector: m => m.Id, elementSelector: m => m); //ApplesId = Dictionary<int, Apple> }
为了复用Pear、Orange这类实现了IDatabaseValue(包含int Id和string Name字段)类型的加载逻辑,你封装了泛型方法:
public void LoadData<T>(IEnumerable<T> t, List<T> l, Dictionary<int, T> d) where T : IDatabaseValue { l.Clear(); l.AddRange(t); d = l.ToDictionary(keySelector: m => m.Id, elementSelector: m => m); }
但调用LoadData(apples, _apples, AppleId);后,List能正常填充数据,Dictionary却没同步更新——问题出在引用类型的参数传递逻辑:
List能正常更新是因为你调用的是Clear()和AddRange()方法,操作的是传入的List对象本身;而Dictionary你直接给d赋值了ToDictionary()返回的新对象,此时方法里的d变量指向了新字典,和外部的AppleId变量彻底断开关联,自然不会更新原对象。
两种常用解决办法:
方案一:用ref关键字传递字典参数
修改泛型方法的参数定义,给字典加上ref,让方法里对d的赋值直接作用于外部的字典变量:
public void LoadData<T>(IEnumerable<T> t, List<T> l, ref Dictionary<int, T> d) where T : IDatabaseValue { l.Clear(); l.AddRange(t); d = l.ToDictionary(keySelector: m => m.Id, elementSelector: m => m); }
调用时也要加上ref关键字:
LoadData(apples, _apples, ref AppleId);
方案二:操作原字典对象而非重新赋值
不创建新字典,而是清空原字典后重新添加键值对,全程操作传入的原字典对象:
public void LoadData<T>(IEnumerable<T> t, List<T> l, Dictionary<int, T> d) where T : IDatabaseValue { l.Clear(); l.AddRange(t); // 清空原字典再批量添加新数据 d.Clear(); foreach (var item in l) { d[item.Id] = item; } // 也可以用LINQ简化写法: // l.ForEach(item => d[item.Id] = item); }
这种方式不需要修改原调用代码,直接用LoadData(apples, _apples, AppleId);即可生效。
内容的提问来源于stack exchange,提问作者M Kr
相关产品推荐
相关产品推荐

