C#中如何获取Dictionary内存储值的引用?
C# Dictionary获取元素引用的方案
首先明确结论:分你存储的是引用类型还是值类型两种情况,都可以实现直接修改Dictionary内部存储值的需求。
另外先纠正一个使用误区:dictionary_.ElementAt(id)是LINQ提供的遍历取序位元素的方法,Dictionary本身是无序的哈希表结构,元素增删都会改变内部迭代顺序,用ElementAt取值不仅性能极低,还很容易拿到错误的元素。如果是按Key匹配元素,一定要用dictionary_[key]索引器访问。
场景1:Dictionary存储引用类型(class实例)
你不需要做任何额外操作,正常获取到的对象本身就是堆实例的引用,修改其属性会直接同步到Dictionary内部的存储对象:
// 单例内的定义示例 public Dictionary<int, 自定义类> dictionary_ = new Dictionary<int, 自定义类>(); // 外部访问代码 var target = 单例实例.dictionary_[你的Key]; target.属性名 = "修改后的值"; // 此处修改直接生效,不需要写回Dictionary
场景2:Dictionary存储值类型(struct、int、bool等值类型)
默认取值是值拷贝,修改拷贝不会影响Dictionary内的原值,需要拿引用的话可以用C#官方提供的高性能方法:
C# 7.0+ 推荐方案
用System.Runtime.InteropServices下的CollectionsMarshal.AsRef直接获取值的引用,无额外拷贝:
using System.Runtime.InteropServices; // 示例Dictionary为Dictionary<string, int> ref int 数值引用 = ref CollectionsMarshal.AsRef(单例实例.dictionary_, "你的Key"); 数值引用 = 1024; // 直接修改Dictionary内的原值,不需要重新赋值
低版本C#兼容方案
没有ref返回支持的话,只能先取值修改后再手动写回:
var tempVal = 单例实例.dictionary_["你的Key"]; tempVal = 1024; 单例实例.dictionary_["你的Key"] = tempVal; // 手动写回更新Dictionary内的值
注意事项
- 单例全局访问的场景下如果涉及多线程读写,要做好线程同步,或者直接改用线程安全的
ConcurrentDictionary避免数据竞争 - 不要长时间持有
ref引用,避免Dictionary扩容、元素删除后引用失效的问题
内容的提问来源于stack exchange,提问作者Zazza
相关产品推荐
相关产品推荐

