2010-07-22 34 views
3

我在C#中使用動態字典。我面臨的問題是我在動態字典類中重寫的TryGetMember的行爲。C#中的動態字典用法#

下面是動態詞典的代碼。

class DynamicDictionary<TValue> : DynamicObject 
{ 
    private IDictionary<string, TValue> m_dictionary; 

    public DynamicDictionary(IDictionary<string, TValue> a_dictionary) 
    { 
     m_dictionary = a_dictionary; 
    } 

    public override bool TryGetMember(GetMemberBinder a_binder, out object a_result) 
    { 
     bool returnValue = false; 

     var key = a_binder.Name; 
     if (m_dictionary.ContainsKey(key)) 
     { 
      a_result = m_dictionary[key]; 
      returnValue = true; 
     } 
     else    
      a_result = null; 

     return returnValue; 
    } 
} 

這裏,TryGetMember會在運行時調用,只要我們從外地指一些關鍵,但奇怪的是粘合劑的名稱成員總是給人關鍵是我們從外面是指,它總是解決寫成字符鍵名的字母。

例如如果DynamicDictionary的對象作出:

Dictionary<string,List<String>> dictionaryOfStringVsListOfStrings; 

//here listOfStrings some strings list already populated with strings 
dictionaryOfStringVsListOfStrings.Add("Test", listOfStrings); 
dynamic dynamicDictionary_01 = new 
    DynamicDictionary<List<String>(dictionaryOfStringVsListOfStrings); 

string somekey = "Test"; 

//will be resolve at runtime 
List<String> listOfStringsAsValue = dynamicDictionary_01.somekey 

現在這裏發生的事情是「somekey」將成爲a_binder(即a_binder.Name =「somekey」)的值。它應該被解析爲a_binder.Name =「Test」,然後從動態字典中找到listOfStrings對這個鍵(即實際上是「Test」,但它不解決這個值,而是實際的變量名作爲鍵)。

有沒有辦法解決這個問題?

回答

5

動態類型化的關鍵是讓成員名自己從源代碼成員訪問中解析出來。

動態類型是完全相同的工作,因爲它的意思在這裏 - 這不是設計檢索變量的值,並用其作爲成員的名字 - 它的設計使用您在源代碼中使用的成員名稱(即「somekey」)。

這聽起來像你真的不需要動態類型都在這裏 - 只是用Dictionary<string,List<String>>正常:

List<String> listOfStringsAsValue = dictionary[somekey]; 

編輯:這聽起來像你真的想封裝這樣的詞典:

public class Foo // TODO: Come up with an appropriate name :) 
{ 
    private readonly Dictionary<string, List<string>> dictionary = 
     new Dictionary<string, List<string>>(); 

    public List<string> this[string key] 
    { 
     get 
     { 
      List<string> list; 
      if (!dictionary.TryGetValue(key, out list)) 
      { 
       list = new List<string>(); 
       dictionary[key] = list; 
      } 
      return list; 
     } 
    } 
} 

然後,你可以這樣做:

foo["first"].Add("value 1"); 
foo["second"].Add("value 2") 
foo["first"].Add("value 1.1"); 

如果你希望能夠ŧ o嘗試獲取列表而不創建新列表,如果該列表不存在,則可以添加一個方法來完成此操作。

這聽起來確實不像你需要動態對象。

+0

可能沒有正確使用動態字典,但超出正常的字典使用情況在我的情況下不起作用。 我的密鑰是隨機填充的,而且沒有任何實際上是字符串(實際上將添加到該密鑰列表中)的那些密鑰的序列值正在添加。在動態字典中,我們只是引用鍵並返回值(即字符串列表),如果我在列表中添加字符串,它實際上會被添加到所提及的列表的下方並指定要動態填充的值的鍵。 – Usman 2010-07-22 13:31:15

+0

@Usman:這聽起來完全可以用普通字典來完成。編輯... – 2010-07-22 13:59:32

+0

感謝喬恩.. 它得到解決。 – Usman 2010-07-22 16:26:56