在c#中在运行时将expando属性添加到类型化对象

在.net中是否有任何方法可以在运行时将属性字典绑定到实例,即,基本对象类具有如下属性:

public IDictionary Items { get; } 

我想出了一个涉及静态字典和扩展方法的解决方案

 void Main() { var x = new object(); x.Props().y = "hello"; } static class ExpandoExtension { static IDictionary props = new Dictionary(); public static dynamic Props(this object key) { dynamic o; if (!props.TryGetValue(key, out o)){ o = new ExpandoObject(); props[key] = o; } return o; } } 

但这会阻止对象获取GC,因为props集合包含引用。 事实上,这对我的特定用例来说还不错,因为一旦我完成了我正在使用它们的特定事物,我就可以手动清除道具,但是我想知道,是否有一些狡猾的方式来绑定ExpandoObject到键,同时允许垃圾收集?

看看ConditionalWeakTable Class 。

ConditionalWeakTable 类使语言编译器能够在运行时将任意属性附加到托管对象。 ConditionalWeakTable 对象是一个字典,它将一个由密钥表示的托管对象绑定到其附加属性,该属性由值表示。 对象的键是附加属性的TKey类的各个实例,其值是分配给相应对象的属性值。

本质上,它是一个字典,其中键和值都被弱引用,只要键处于活动状态,值就会保持活动状态。


 static class ExpandoExtensions { private static readonly ConditionalWeakTable props = new ConditionalWeakTable(); public static dynamic Props(this object key) { return props.GetOrCreateValue(key); } } 

您可以使用WeakReference来引用对象,以便它们仍然可以进行垃圾回收。 你仍然需要手工清理你的字典,因为对象本身就被破坏了。