C# Dictionary能否同时存储普通对象与对象列表两种类型的值?
方案1:使用object作为字典值类型(快速实现)
直接修改字典的泛型声明,取值时判断类型即可适配单/多值场景:
public Dictionary<string, object> testDictionary = new Dictionary<string, object>(); // 元素添加逻辑 if (!testDictionary.ContainsKey(testObjId)) { // 首次添加直接存TestObj实例,避免List的额外开销 testDictionary.Add(testObjId, new TestObj(testObjId)); } else { var existingValue = testDictionary[testObjId]; if (existingValue is TestObj singleObj) { // 第二次添加时升级为List存储 testDictionary[testObjId] = new List<TestObj> { singleObj, new TestObj(testObjId) }; } else if (existingValue is List<TestObj> objList) { // 已有List直接追加元素 objList.Add(new TestObj(testObjId)); } } // 封装统一取值方法示例 public IEnumerable<TestObj> GetTestObjs(string id) { if (!testDictionary.TryGetValue(id, out var value)) return Enumerable.Empty<TestObj>(); return value switch { TestObj singleObj => new[] { singleObj }, List<TestObj> objList => objList, _ => Enumerable.Empty<TestObj>() }; }
方案2:自定义类型安全包装类(生产环境推荐)
第一种方案存在运行时类型转换的风险,你可以封装专用存储类,对外屏蔽单/多值的实现差异,同时保证类型安全:
public class TestObjStorage { private TestObj _singleInstance; private List<TestObj> _instanceList; public void Add(TestObj obj) { if (_instanceList != null) { _instanceList.Add(obj); return; } if (_singleInstance == null) { _singleInstance = obj; return; } // 单值场景升级为多值场景 _instanceList = new List<TestObj> { _singleInstance, obj }; _singleInstance = null; } public IEnumerable<TestObj> GetAll() { if (_instanceList != null) return _instanceList; if (_singleInstance != null) return new[] { _singleInstance }; return Enumerable.Empty<TestObj>(); } public int Count => _instanceList?.Count ?? _singleInstance != null ? 1 : 0; }
对应字典声明修改为:
public Dictionary<string, TestObjStorage> testDictionary = new Dictionary<string, TestObjStorage>();
添加元素的逻辑会更简洁:
if (!testDictionary.TryGetValue(testObjId, out var storage)) { storage = new TestObjStorage(); testDictionary.Add(testObjId, storage); } storage.Add(new TestObj(testObjId));
该方案完全适配绝大多数单元素场景的低内存需求,同时避免了运行时类型转换出错的风险。
内容的提问来源于stack exchange,提问作者Rakshith Gowda GS
相关产品推荐
相关产品推荐

