如何冻结动态对象?Dump后修改仍显示后续变更的问题咨询
解决LINQPad中动态对象Dump后被修改的问题
问题场景:使用ExpandoObject时,执行Dump后给动态对象新增属性,发现之前的Dump结果里显示了新增的属性,不符合预期。
核心原因
ExpandoObject是引用类型,LINQPad的Dump功能默认展示对象的实时状态,后续对原对象的修改会同步反映到已Dump的视图中。要避免这种情况,需要在Dump时创建对象当前状态的独立副本。
解决方案
方法1:转换为匿名类型
将ExpandoObject的现有属性复制到匿名对象中,Dump这个匿名对象,后续修改原动态对象不会影响已Dump的内容:
void Main() { List<ExpandoObject> lo= new List<ExpandoObject>(); dynamic eo = new ExpandoObject(); eo.first="originalvaluebeforefirstdump"; lo.Add(eo); // 复制当前属性到匿名对象后Dump var frozenSnapshot = new { first = eo.first }; new List<object> { frozenSnapshot }.Dump("firstdump"); eo.second="newvaluesaftefirstdump"; }
方法2:转换为字典副本
利用ExpandoObject实现IDictionary<string, object>的特性,创建一个独立的字典副本,Dump这个副本:
void Main() { List<ExpandoObject> lo= new List<ExpandoObject>(); dynamic eo = new ExpandoObject(); eo.first="originalvaluebeforefirstdump"; lo.Add(eo); // 创建当前状态的字典副本 var frozenDict = new Dictionary<string, object>((IDictionary<string, object>)eo); new List<Dictionary<string, object>> { frozenDict }.Dump("firstdump"); eo.second="newvaluesaftefirstdump"; }
方法3:自定义冻结扩展方法(通用方案)
如果需要频繁处理这类场景,可以写一个扩展方法,将ExpandoObject转换为不可变的字典:
public static class ExpandoExtensions { public static IReadOnlyDictionary<string, object> Freeze(this ExpandoObject eo) { return new Dictionary<string, object>(eo).AsReadOnly(); } } void Main() { List<ExpandoObject> lo= new List<ExpandoObject>(); dynamic eo = new ExpandoObject(); eo.first="originalvaluebeforefirstdump"; lo.Add(eo); // 调用扩展方法冻结后Dump lo.Select(e => e.Freeze()).Dump("firstdump"); eo.second="newvaluesaftefirstdump"; }
内容的提问来源于stack exchange,提问作者junkone
相关产品推荐
相关产品推荐

