[英]How to correctly implement the IDictionary interface and subclass from it
我的目標是擁有一個具有唯一鍵和值的字典,而我正在使用其他HashSet進行解決。 我想有一個基類,從中可以繼承更多特定的類型。
據我了解,字典類的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
為鍵, 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'.
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
to的參數(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;
}
如果我傳遞1
,則此GetValue
方法始終會拋出實現的異常,但我並不真正理解為什么。 我調試了代碼,可以看出'InternalDict'實際上確實擁有鍵1
和值foobar. The
myDict call on
foobar. The
TryGetValue call on
jumps into the implementation of the
BaseCustomDictionary class and writes an empty string into the
jumps into the implementation of the
class and writes an empty string into the
value變量。
當然,現在我可以在子類中實現自己的TryGetValue
了,但是如果我必須實現每個方法,那似乎就無法實現擁有子類的目的。
public bool TryGetValue(TKey key, out int value) {
return InternalDict.TryGetValue(key, out value);
}
我覺得我在繼承方面做的根本上是錯誤的。
子類沒有理由通用。 其存在的原因是為其基類指定類型參數。 這樣聲明子類:
public class IntStringDictionary : BaseCustomDictionary<int,String>
{
}
如果您的基類不是抽象的,則無需為此實現任何成員。 實際上,我不清楚您為什么不像使用Dictionary
那樣直接實例化BaseCustomDictionary<int, String>
,但是有充分的理由將子類與您的問題無關。
順便說一句,通用庫中的代碼不會編譯:
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);
}
由於以下原因,您做錯了事情:
公共類IntStringDictionary:BaseCustomDictionary
要創建具有與BaseCustomDictionary
相同功能的int字符串字典, 請不要繼承。 您只需:
var myDict = new BaseCustomDictionary<int, string>();
就那么簡單!
僅當要向BaseCustomDictionary
添加新功能時才繼承。 根據您的問題,我看不到要添加到BaseCustomDictionary
新行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.