.net中是否有任何方法可以在运行时将属性字典绑定到实例,即基本对象类具有如下属性:
public IDictionary Items { get; }
我提出了一个涉及静态字典和扩展方法的解决方案
void Main()
{
var x = new object();
x.Props().y = "hello";
}
static class ExpandoExtension {
static IDictionary<object, dynamic> props = new Dictionary<object, dynamic>();
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扩展到密钥?
答案 0 :(得分:11)
查看ConditionalWeakTable<TKey, TValue> Class。
ConditionalWeakTable&lt; TKey,TValue&gt; class使语言编译器能够在运行时将任意属性附加到托管对象。 ConditionalWeakTable&lt; TKey,TValue&gt; object是一个字典,它将一个由密钥表示的托管对象绑定到其附加属性,该属性由值表示。对象的键是附加属性的TKey类的各个实例,其值是分配给相应对象的属性值。
本质上它是一个字典,其中键和值都被弱引用,只要键处于活动状态,值就会保持活动状态。
static class ExpandoExtensions
{
private static readonly ConditionalWeakTable<object, ExpandoObject> props =
new ConditionalWeakTable<object, ExpandoObject>();
public static dynamic Props(this object key)
{
return props.GetOrCreateValue(key);
}
}
答案 1 :(得分:0)
您可以使用WeakReference来引用对象,以便它们仍然可以进行垃圾回收。你仍然需要手工清理字典,因为对象本身就会被破坏。