如何正确实现 IDictionary 接口和它的子类
How to correctly implement the IDictionary interface and subclass from it
我的目标是拥有一个具有唯一键 和 值的字典,我正在用一个额外的 HashSet 来解决这个问题。我想要一个基础 class,从中继承更多特定类型。
据我了解,字典 class 的 add-Method 不是虚拟的,因此不能被覆盖。因此,唯一的方法就是实现 IDictionary 接口。
所以我的基础字典class的基本结构是:
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
}
现在我想要一个具体的 subclass,其中 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'.
同意。所以我将 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;
}
如果我通过1
,这个GetValue
方法总是抛出实现的异常,我不太明白为什么。我调试了代码,可以看出 'InternalDict' 实际上持有键 1
和值 foobar. The
TryGetValuecall on
myDictjumps into the implementation of the
BaseCustomDictionaryclass and writes an empty string into the
value` 变量。
当然我现在可以在我的 subclass 中实现我自己的 TryGetValue
,但这似乎违背了拥有 subclasses 的目的,如果我必须实现每个方法。
public bool TryGetValue(TKey key, out int value) {
return InternalDict.TryGetValue(key, out value);
}
我觉得我在继承方面做了一些根本性的错误。
subclass没有理由通用;它存在的原因是为其基 class 指定类型参数。像这样声明子class:
public class IntStringDictionary : BaseCustomDictionary<int,String>
{
}
如果您的基础 class 不是抽象的,则您不需要为此实现任何成员。事实上,我不清楚为什么你不像实例化 Dictionary
那样只是实例化 BaseCustomDictionary<int, String>
,但是有正当理由去 subclass 与你的不相关题。
顺便说一下,通用基础中的这个不会编译:
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);
}
你做错事是因为:
public class IntStringDictionary:BaseCustomDictionary
要创建一个与 BaseCustomDictionary
具有相同功能的 int 字符串字典,您 不 继承。你只需做:
var myDict = new BaseCustomDictionary<int, string>();
就这么简单!
只有在您想要向 BaseCustomDictionary
添加新功能时才可以继承。从你的问题来看,我看不出你想在 BaseCustomDictionary
.
中添加什么新行为
我的目标是拥有一个具有唯一键 和 值的字典,我正在用一个额外的 HashSet 来解决这个问题。我想要一个基础 class,从中继承更多特定类型。
据我了解,字典 class 的 add-Method 不是虚拟的,因此不能被覆盖。因此,唯一的方法就是实现 IDictionary 接口。
所以我的基础字典class的基本结构是:
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
}
现在我想要一个具体的 subclass,其中 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'.
同意。所以我将 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;
}
如果我通过1
,这个GetValue
方法总是抛出实现的异常,我不太明白为什么。我调试了代码,可以看出 'InternalDict' 实际上持有键 1
和值 foobar. The
TryGetValuecall on
myDictjumps into the implementation of the
BaseCustomDictionaryclass and writes an empty string into the
value` 变量。
当然我现在可以在我的 subclass 中实现我自己的 TryGetValue
,但这似乎违背了拥有 subclasses 的目的,如果我必须实现每个方法。
public bool TryGetValue(TKey key, out int value) {
return InternalDict.TryGetValue(key, out value);
}
我觉得我在继承方面做了一些根本性的错误。
subclass没有理由通用;它存在的原因是为其基 class 指定类型参数。像这样声明子class:
public class IntStringDictionary : BaseCustomDictionary<int,String>
{
}
如果您的基础 class 不是抽象的,则您不需要为此实现任何成员。事实上,我不清楚为什么你不像实例化 Dictionary
那样只是实例化 BaseCustomDictionary<int, String>
,但是有正当理由去 subclass 与你的不相关题。
顺便说一下,通用基础中的这个不会编译:
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);
}
你做错事是因为:
public class IntStringDictionary:BaseCustomDictionary
要创建一个与 BaseCustomDictionary
具有相同功能的 int 字符串字典,您 不 继承。你只需做:
var myDict = new BaseCustomDictionary<int, string>();
就这么简单!
只有在您想要向 BaseCustomDictionary
添加新功能时才可以继承。从你的问题来看,我看不出你想在 BaseCustomDictionary
.