2012-04-18 147 views
6

是否可以將Dictionary<string, Anything>轉換爲一致的中間泛型類型?所以我可以將<string, string><string, bool>,<string, int>,<string, anything>全部轉換爲相同類型的字典?C#將Dictionary <string,AnyType>轉換爲Dictionary <string,Object>(涉及反射)

我對正在使用重型反射一個項目,我需要能夠處理詞典類型,例如:

FieldInfo field = this.GetType().GetField(fieldName); 
Dictionary<string, Object> dict = (Dictionary<string, Object>)field.GetValue(this); 

上面的代碼是什麼,我現在已經和程序總是在失敗從field.GetValue投射到通用Dictionary<string, Object>

有沒有辦法做到這一點?還是應該找出處理這些字典的不同方法?

任何幫助將不勝感激。

回答

8

AakashM's answer,演員似乎沒有打球。雖然你可以通過使用一個小幫手的方法來解決它:

IDictionary dictionary = (IDictionary)field.GetValue(this); 
Dictionary<string, object> newDictionary = CastDict(dictionary) 
              .ToDictionary(entry => (string)entry.Key, 
                 entry => entry.Value); 

private IEnumerable<DictionaryEntry> CastDict(IDictionary dictionary) 
{ 
    foreach (DictionaryEntry entry in dictionary) 
    { 
     yield return entry; 
    } 
} 

在這種情況下,鴨子在foreach中打字很方便。

+0

這就像一個魅力,謝謝你AakashM和Gibsnag。這給了我一段時間的麻煩。 – 2012-04-18 10:27:31

+2

不需要特殊的CastDict方法,您可以使用普通的Cast ()LINQ運算符。 – 2013-07-03 03:01:34

5

這是幫助你嗎?

Dictionary<a, b> output = 
    input.ToDictionary(item => item.Key, item => (SomeType)item.Value); 
+0

因爲我正在使用反射,所以我實際上無法調用ToDictionary方法。我可能能夠使用更多的反射去到ToDictionary方法,但是我不確定如何將這些參數傳遞給它。 – 2012-04-18 09:35:32

8

即使你能找到一些方式來表達這一點,那將是錯誤的做法 - 一個Dictionary<string, bool>一個Dictionary<string, object>這不是真的,所以我們絕對不希望 。考慮一下,如果我們可以投下,我們可以嘗試將string作爲一個值,這顯然不適合!

我們所能做的,然而,投射到非通用IDictionary(所有Dictionary<,>小號器),然後用它來構建一個Dictionary<string, object>具有相同的價值觀:

FieldInfo field = this.GetType().GetField(fieldName); 
IDictionary dictionary = (IDictionary)field.GetValue(this); 
Dictionary<string, object> newDictionary = 
    dictionary 
    .Cast<dynamic>() 
    .ToDictionary(entry => (string)entry.Key, 
        entry => entry.Value); 

(請注意,您不能使用.Cast<DictionaryEntry>這裏the reasons discussed here。如果你是前C#4,所以沒有dynamic,你必須手動進行枚舉,如Gibsnag's answer does

+0

我仍然收到錯誤「指定的轉換無效」與該代碼。有任何想法嗎? – 2012-04-18 10:06:47

+0

'field.GetValue()'返回的對象的實際類型是什麼? – AakashM 2012-04-18 10:09:48

+0

好吧,我知道它試圖獲得一個'Dictionary ',但這只是因爲它是我的第一個測試用例。在運行時'Console.WriteLine(field.GetValue(this).GetType()。Name);'打印出'字典'2「。編輯:我剛剛跑'Console.WriteLine(field.GetValue(this));'得到了'System.Collections.Generic.Dictionary'2 [System.String,System.String]' – 2012-04-18 10:13:23

0

是有可能鑄就FieldInfoDictionary如下

這是一個例子,我在我的代碼

Dictionary<string, string> 
       GetTheDict = FilesAndPaths.GetType() 
          .GetFields() 
          .Where(f => f.Name.Equals(pLoadFile)) 
          .Select(f => (Dictionary<string, string>)f.GetValue(FilesAndPaths)) 
          .Single(); 
0

已經使用考慮是否鑄造和object確實是必要的。我開始了這條路,偶然發現了這篇文章,然後才意識到我可以通過泛型而不是轉換來實現我所需要的。例如;

class DictionaryUtils<T> 
{ 
    public static T ValueOrDefault(IDictionary<string, T> dictionary, string key) 
    { 
     return dictionary.ContainsKey(key) ? dictionary[key] : default(T); 
    } 
} 

這段代碼比其他答案中顯示的等效轉換代碼要乾淨得多。

相關問題