如何正确实现 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. TheTryGetValuecall onmyDictjumps into the implementation of theBaseCustomDictionaryclass and writes an empty string into thevalue` 变量。

当然我现在可以在我的 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.

中添加什么新行为