2017-08-03 94 views
2

請考慮以下情況。我有一個Dictionary<string,string> dictionary和一個string key。在編譯時我不知道這兩種類型,但我在運行時知道它們。所以在編譯時,它們只是對象。我想要調用dictionary.ContainsKey(key)。但是,因爲key是一個「轉換爲對象」的字符串,所以會產生RuntimeBinderException。我想了解如何解決此問題。如何將對象轉換爲僅在運行時才知道的類型

這裏有一些測試表明該問題:

[TestMethod] 
    public void ThisTestFails() 
    { 
     dynamic dictionary = getDict(); 
     var key = getKey(); 

     bool result = dictionary.ContainsKey(key); 
     Assert.IsTrue(result); 
    } 

    [TestMethod] 
    public void ThisTestWorks() 
    { 
     dynamic dictionary = getDict(); 
     var key = (string)getKey(); 

     bool result = dictionary.ContainsKey(key); 
     Assert.IsTrue(result); 
    } 

    private object getDict() => new Dictionary<string, string>() { { "abc", "def" } }; 
    private object getKey() => "abc"; 

ThisTestFails失敗並RunTimeBinderException,而ThisTestWorks通行證。所以,發生的是,雖然兩個測試中的key變量都包含一個字符串,但它在ThisTestFails中的明顯類型是一個對象,不能在dictionary.ContainsKey中使用。

我需要解決這個問題,本質上是一種在運行時將「key」變量「鑄造」成字符串的方法。 ThisTestWorks中的(string)key解決方案對我無用,因爲我在一般情況下在編譯時不知道字典鍵的類型。可以做些什麼來解決這個問題?

+1

爲什麼在編譯時未知鍵的實際類型時,字典是否使用'string'類型鍵?你是否考慮過簡單地使用'object'類型作爲鍵?當你的字典的鍵可以是「任何類型的對象」,那麼恕我直言,它使用'對象'類型來表示鍵(而不是使用文本)更有意義。 – bassfader

+0

那麼,字符串鍵和值只是例子。實際上,字典是通過反射找到的,並且具有非常明智的泛型類型參數,但是在客戶端運行時只是未知,因爲字典可能來自不同類別的屬性。所以沒有對象作爲關鍵類型有很好的理由。 –

+1

這可能是一個XY問題,所以也許你可能會從分享你試圖解決的實際問題中受益。在很多情況下,C#中可以避免使用'dynamic'。 – Groo

回答

2

您好我認爲您正在尋找這樣的事情

dynamic dictionary = getDict(); 
dynamic key = getKey(); 

bool result = (bool)dictionary.ContainsKey(key); 
Assert.IsTrue(result); 

但這裏可能是因爲你正在試圖尋找這是在「對象」型盒裝的字符串(這種類型是從返回的另一個問題你的方法像GetKey()),所以在包含關鍵字方法比較中,就像對於字符串的對象類型含義一樣,不是通過引用值來完成。

+0

你確定'字符串是盒裝? –

+0

嗨@ C.Evenhuis,getKey返回'對象',所以我很肯定它會被裝箱,但是我沒有測試它 –

+0

似乎工作。謝謝! –

相關問題