2017-01-24 93 views
0

我的目標是擁有一個字典,其中包含唯一鍵值,我正在使用其他HashSet解決這個問題。我想有一個基類,從中繼承更多特定的類型。如何正確實現IDictionary接口及其子類

據我所知,字典類的add-Method不是虛擬的,因此不能被重寫。所以唯一的方法就是實現IDictionary接口。

所以我的基礎字典類的基本結構是:

public class BaseCustomDictionary<TKey,TValue>:IDictionary<TKey,TValue> { 
    public virtual Dictionary<TKey,TValue> InternalDict { 
     get; 
     set; 
    } 

    public BaseCustomDictionary() { 
     this.InternalDict = new Dictionary<TKey,TValue>(); 
    } 

    // Here I start implementing all the required methods, e.g. Add, TryGetValue 
    public virtual void Add(TKey key, TValue value) { 
     InternalDict.Add(key, value); 
    } 

    public bool TryGetValue (TKey key, out string value) { 
     return InternalDict.TryGetValue (key, out value); 
    } 

    // And so on and so forth 
} 

現在我想有一個具有int S作爲鍵和string爲值的具體子類:

public class IntStringDictionary<TKey,TValue>:BaseCustomDictionary<TKey,TValue> { 
    public override Dictionary<int,string> InternalDict { 
     get; 
     set; 
    } 

    HashSet<string> UniqueValues; 

    public IntStringDictionary() { 
     InternalDict = new Dictionary<int,string>(); 
     UniqueValues = new HashSet<string>(); 
    } 

    public override void Add (TKey key, TValue value) { 
     if (InternalDict.ContainsKey (key)) { 
      return; 
     } 

     string randomStr = RandomString(); 

     if (!UniqueValues.Add(randomStr)) { 
      Add(key,value); 
      return; 
     } else { 
      InternalDict.Add(key,randomStr); 
      return 
     } 
    } 
} 

這裏我遇到各種各樣的問題。 首先是The best overloaded method match for 'System.Collections.Generic.Dictionary<int,string>.ContainsKey(string) has some invalid arguments'. Cannot convert type 'TKey' to 'string'.同意。因此,我將InternalDict更改爲new Dictionary<TKey,short>(),將Add更改爲(TKey key, TValue value)

接下來的問題是如何訪問方法。說我的實現是這樣的:

public static IntStringDictionary<int,string> myDict = new IntStringDictionary<int,string>(); 

// Assuming the class is named Constructor 
public Constructor() { 
    myDict.Add(1,"foobar"); 
} 

public static string GetValue (int key) { 
    string value; 
    myDict.TryGetValue(key, out value); 

    if (value == '') { 
     throw new NullReferenceException ("Value not found for given key"); 
    } 

    return value; 
} 

GetValue方法總是拋出異常實現如果我通過1,我真的不明白爲什麼。我調試了代碼,可以看出'InternalDict'實際上確實保存了密鑰1和值foobar. The TryGetValue call on myDict jumps into the implementation of the BaseCustomDictionary class and writes an empty string into the value` variable。

當然,我現在可以在我的子類中實現我自己的TryGetValue,但是如果必須實現每種方法,那似乎會破壞具有子類的目的。

public bool TryGetValue(TKey key, out int value) { 
    return InternalDict.TryGetValue(key, out value); 
} 

我覺得我正在做一些根本性的繼承錯誤。

回答

0

該子類沒有理由是通用的;其存在的原因是爲其基類指定類型參數。聲明這樣的子類:

public class IntStringDictionary : BaseCustomDictionary<int,String> 
{ 
} 

如果您的基類不是抽象的,那麼您不應該需要實現任何成員。實際上,我不清楚爲什麼你不只是實例化BaseCustomDictionary<int, String>,就像你會用Dictionary一樣,但是有一些正確的理由來描述與你的問題無關的子類。

順便說一句,這在通用基礎將無法編譯:

public bool TryGetValue (TKey key, out string value) { 
    return InternalDict.TryGetValue (key, out value); 
} 

這意志 - value參數需要TValue。但我猜這只是在撰寫你的問題時的複製和粘貼錯誤。

public bool TryGetValue (TKey key, out TValue value) { 
    return InternalDict.TryGetValue (key, out value); 
} 
0

你錯誤地做的事情,因爲這樣的:

公共類IntStringDictionary:BaseCustomDictionary

創建具有相同的功能作爲一個BaseCustomDictionary INT串字典,你繼承。你只是這樣做:

var myDict = new BaseCustomDictionary<int, string>(); 

就這麼簡單!

只有當您想要將新功能添加到BaseCustomDictionary時纔會繼承。從你的問題,我看不到你想添加到你的新行爲BaseCustomDictionary

+0

它主要是'Add'方法。根據我的值的類型,我將調用不同的方法來生成僞隨機值。否則我不知道如何在'BaseCustomDictionary'類中添加這種區別。 – ShitakeOishii

+0

對不起,我沒有注意到添加方法。但是你的Add方法實現看起來很奇怪。我認爲你應該把這個邏輯留給字典類的用戶。另一種方法是將擴展方法添加到BaseCustomDictionary中。 – Sweeper