2017-02-27 68 views
0

我想要的是Dictionary<string, T>,其中T僅限於幾種類型之一。限制C#字典中的值類型:

如果C#有打字稿聯合類型它會看起來像Dictionary<string, bool | string | int | List<string> | List<int>>

我所做的是寫周圍字典的包裝類,它有一堆的Add()個人支持的類型重載的,像GetBool()GetString()的方法恢復。請參閱http://pastebin.com/av7nE5az

此方法有效,但冗長且冗長乏味,我認爲必須有更好的方法。有人得到一個?

編輯:關於爲什麼我想要這個的一些問題。基本上我想Dictionary<string, object>,一個實例可能包含多種類型的值,但我希望以一種限制的方式(在遊戲中)使用它,所以可能的值類型的列表是有限的。我可以通過僅使用Dictionary<string, object>並投射每個檢索來獲得,但我認爲如果我可以在數據結構本身中構建更多類型意識,它會更好。

+0

只能限制噸至一個基本類型,由於int'和'名單'之間唯一的公共基類''是object'沒有辦法來限制'T'任何進一步。 –

+0

如果C#允許'Dictionary |列表>',因爲在編譯時不會知道值的類型,所以迭代集合時會丟失類型安全性。我不知道你在努力達到什麼樣的目標,但是聽起來像一個包裝類可能是要走的路。 – PoweredByOrange

+0

@PoweredByOrange我認爲OP要允許'Dictionary '和'Dictionary '但不能'Dictionary ' - 不允許在一個字典中使用多個值類型。 –

回答

1

如果您的目標是更簡單的代碼和編譯時類型檢查,您可以使用此方法,但它可能會略微影響性能。

  1. 定義你的字典作爲Dictionary<string, MyEntry>

  2. 寫了一類新MyEntry能夠儲存所有數據類型的興趣的。

  3. implicit conversion operatorsMyEntry和感興趣的數據類型。它可能看起來像這個例子中,它可以處理boolint(你可以擴展爲其它數據類型需要):

    class MyEntry 
    { 
        private Type _type = typeof(object); 
        private bool _boolValue = false; 
        private int _intValue = 0; 
    
        public MyEntry(bool b) 
        { 
         _type = typeof(bool); 
         _boolValue = b; 
        } 
    
        public MyEntry(int i) 
        { 
         _type = typeof(int); 
         _intValue = i; 
        } 
    
        public static implicit operator bool(MyEntry e) 
        { 
         if (e._type != typeof(bool)) throw new InvalidCastException(); 
         return e._boolValue; 
        } 
        public static implicit operator MyEntry(bool b) 
        { 
         return new MyEntry(b); 
        } 
        public static implicit operator int(MyEntry e) 
        { 
         if (e._type != typeof(int)) throw new InvalidCastException(); 
         return e._intValue; 
        } 
        public static implicit operator MyEntry(int i) 
        { 
         return new MyEntry(i); 
        } 
    } 
    
  4. 然後,您可以編寫簡潔的代碼讀取和本字典寫不明確管型。您可以通過限制爲MyEntry實施的隱式強制轉換來控制允許的類型。

    var d = new Dictionary<string, MyEntry>(); 
    d.Add("IntegerOne", 1); 
    d.Add("BooleanTrue", true); 
    d.Add("FloatThree", 3.0f); //Will not compile 
    
    bool b = d["BooleanTrue"]; 
    int i = d["IntegerOne"]; 
    float f = d["FloatThree"]; //Will not compile 
    
    Console.WriteLine(string.Format("BooleanTrue = '{0}'", b)); 
    Console.WriteLine(string.Format("IntegerOne = '{0}'", i)); 
    
+0

這很有趣,可能有用(性能可能會很好)。我會試試看,謝謝。 – Matt