2011-03-05 55 views
5

是否有.NET任何方式结合性质的字典来在运行时,即,例如,如,如果基对象类有属性,如:添加expando属性的类型的对象在运行时,在c#

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'd作为道具收集停止对象保持一个参考。实际上,这对我的特殊使用情况来说确实很好,因为我可以在完成使用它们的特定事件后手动清除道具,但是我想知道,是否有一些巧妙的方法可以将在允许垃圾收集的同时将ExpandoObject转换为密钥?

回答

11

看看ConditionalWeakTable<TKey, TValue> Class

的ConditionalWeakTable < TKEY的,TValue >类允许语言编译器在运行时任意属性附加到管理对象。一个有条件的WeakTable < TKey,TValue > 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);  
    } 
} 
+3

我必须承认我不知道这个存在。 – 2011-03-05 14:42:45

+0

谢谢你,那是完美的 – mcintyre321 2011-03-05 15:03:29

0

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

+0

我看看这个,但离开时认为必须有一个更简单的方法!在上面的例子中,我们必须能够使用x来查找ExpandoObject,但实际上并没有将x存储在道具字典中。为了解决这个问题,我考虑使用Dictionary >,通过执行GetHashcode()来存储内容,然后通过列表中的动态列表来搜索关键对象的WeakReference。不是很好,Expandos仍然没有GC'd。 我想出了一个Dictionary > – mcintyre321 2011-03-05 14:40:11

+0

@ mcintyre321:看来你运气好,有人已经为你实现了你的字典。 – 2011-03-05 14:43:14