2015-10-25 67 views
0

我有一個C#程序,我需要查找基於鍵的數據。 我將我的Python代碼移植到C#中,發現難以實現嵌套Python字典的等效功能。經過多次嘗試使用C#字典後,我決定使用Hashtable,因爲它是鬆散類型的。如何訪問C#中的嵌套散列表值

我可以寫入我的嵌套Hashtable結構,如果迭代,我可以讀取它。但我想要做的是訪問基於特定鍵的特定數據。

這裏是我使用的代碼,它的工作原理:

 foreach (DictionaryEntry x in ParameterTypes) 
     { 
      Console.WriteLine(x.Key + " -- "); 
      foreach (DictionaryEntry y in x.Value as Hashtable) 
      { 
       Console.WriteLine(y.Key + ": " + y.Value); 
      } 
      Console.WriteLine("\n"); 
     } 

它給了我這個輸出(樣本):

EVENT_PARAM_SCTP_SHUTDOWN_RESULT -
名稱:EVENT_PARAM_SCTP_SHUTDOWN_RESULT
usevalid:是
說明:SCTP關機結果
numberofbytes:1
type:ENU中號

EVENT_PARAM_ENBS1APID -
名:EVENT_PARAM_ENBS1APID
numberofbytes:3
usevalid:是
描述:eNB的S1 AP ID
分辨率:1
類型:UINT

然而,以下代碼不起作用:

Console.WriteLine(ParameterTypes["EVENT_PARAM_ENBS1APID"]["description"]); 

當我試圖獲取基於鍵和嵌套鍵的數據時,正確的方法是什麼?

+1

您應該切換到'DIivingary ' – SLaks

+0

我花了整整一天的時間試圖使用字典,並放棄了,去散列表,而不是寬鬆的打字。我的密鑰可能會有所不同,值的類型可能會有所不同,並且在某些情況下,我有第三級嵌套,爲了清晰起見,此處未顯示。 – hacker101

+1

這聽起來像個糟糕的主意。你應該重新考慮你的設計是更安全的。 – SLaks

回答

0

這段代碼產生你似乎期望輸出...

using System; 
using System.Collections; 
using System.Collections.Generic; 

namespace TestProject 
{ 
    /// <summary> 
    /// Parameter entry for ParameterTypes collection. 
    /// </summary> 
    class ParameterEntry : Dictionary<string, object> 
    { 
     // this is just an subclassed Dictionary class 
    } 

    /// <summary> 
    /// Parameter types collection. 
    /// </summary> 
    class ParameterTypes : Dictionary<string, ParameterEntry> 
    { 
     // this class is a Dictionary that holds ParameterEntry objects 

     /// <summary> 
     /// Add the specified value using its name as the key. 
     /// </summary> 
     /// <param name='value'> 
     /// A parameter entry. 
     /// </param> 
     public void Add(ParameterEntry value) 
     { 
      string key = (string)value["name"]; 
      this.Add(key, value); 
     } 
    } 

    class TestProject 
    { 
     public static void Main (string[] args) 
     { 
      var entry1 = new ParameterEntry(); 
      entry1.Add("name", "EVENT_PARAM_SCTP_SHUTDOWN_RESULT"); 
      entry1.Add("usevalid", "Yes"); 
      entry1.Add("description", "The results of a SCTP Shutdown"); 
      entry1.Add("numberofbytes", 1); 
      entry1.Add("type", "ENUM"); 

      var entry2 = new ParameterEntry(); 
      entry2.Add("name", "EVENT_PARAM_ENBS1APID"); 
      entry2.Add("numberofbytes", 3); 
      entry2.Add("usevalid", "Yes"); 
      entry2.Add("description", "eNB S1 AP ID"); 
      entry2.Add("resolution", 1); 
      entry2.Add("type", "UINT"); 

      var types = new ParameterTypes(); 
      types.Add(entry1); 
      types.Add(entry2); 

      Console.WriteLine(types["EVENT_PARAM_ENBS1APID"]["name"]); 
      Console.WriteLine(types["EVENT_PARAM_ENBS1APID"]["numberofbytes"]); 
      Console.WriteLine(types["EVENT_PARAM_ENBS1APID"]["usevalid"]); 
      Console.WriteLine(types["EVENT_PARAM_ENBS1APID"]["description"]); 
     } 
    } 
} 

你當然可以嵌套Dictionary一個Dictionary中,你可以使用字符串作爲主鍵和嵌套按鍵,並使用一個對象作爲最終的嵌套值。您也可以將類型爲Dictionary<>的類作爲您自己的類進行分類,以抽象實現並使代碼更易於閱讀和理解。請記住,如果你來自Python或任何其他鬆散類型的語言,則必須重新考慮如何用C#等強類型語言來解決問題。

+0

這真是太棒了,我喜歡它看到幾行類定義可以做到這麼多真的讓我感興趣並有動力採用新的思維方式,將代碼和概念融入到我的項目中,並且工作得很好,代碼精簡而乾淨,非常感謝! – hacker101

1

嘗試使用通用字典類型字典,所以你可以存儲嵌套集合:

 Dictionary<string,object> ParameterTypes = new Dictionary<string,object>(); 
    //Populate the parameterTypes here 
    foreach (var x in ParameterTypes) 
    { 
     Console.WriteLine(x.Key + " -- "); 
     foreach (var in x.Value) 
     { 
      Console.WriteLine(y.Key + ": " + y.Value); 
     } 
     Console.WriteLine("\n"); 
    } 

如果您已經定義,你可以使用它的價值類:

Dictionary<string, Dictionary<string,YourType>> or similar 
+0

請參閱響應SLaks的評論。字典不提供足夠的靈活性(強類型),我認爲散列表會更直接(鬆散類型)。我也看到了一些關於使用類的stackexchange問​​答。對於在Python或Perl中出現一個簡單而常見的東西似乎有點深刻,但是可能有一個類「ParameterTypes」並創建它的集合將是解決方案。我希望有一些簡單的東西(我不是專業的程序員)。 – hacker101

+0

然後,你可能想嘗試在c#中的動態類型https://msdn.microsoft.com/en-us/library/dd264736.aspx –

+1

我早些時候嘗試過,但必須得到的語法錯誤。我會再次嘗試,更仔細。 – hacker101

2

我同意其他響應者,你應該重新考慮這個結構,而不是試圖模仿PHP。但如果你想堅持下去,你的雙重索引不起作用的原因是因爲ParameterTypes["EVENT_PARAM_ENBS1APID"]返回一個object,它沒有[]運算符。你必須把它作爲一個Hashtable來重新索引。

首先,您可能需要使用is運算符來確定給定節點是否確實是嵌套哈希表。如果是,你可以去

((Hashtable) ParameterTypes["EVENT_PARAM_ENBS1APID"])["description"] 

(ParameterTypes["EVENT_PARAM_ENBS1APID"] as Hashtable)["description"] 
+0

如何正確投射。語法是什麼?我試過但失敗:( – hacker101

+0

使用提供的語法,試圖將值賦給一個字符串(打印到控制檯)給我一個錯誤「Error 不能隱式地將類型'object'轉換爲'string'。轉換是否存在(是否缺少演員?)「。但是當我把(字符串)放在控制檯前面時,會給我一個空白結果。例如: string result =(string)((Hashtable)ParameterTypes [」EVENT_PARAM_ENBS1APID「 ])[「description」]; – hacker101

+0

@ hacker101我不知道爲什麼你會得到一個空白的結果 –