2011-03-05 58 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