自定义词典中索引器的奇怪行为

时间:2013-03-22 13:28:27

标签: c# generics dictionary

我创建了一个继承自Dictionary的自定义Dictionary类。但是,根据我使用类的方式调用索引器时会发生奇怪的事情。这是该类的简化版本:

public class MyDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
    public new TValue this[TKey key]
    {
        get
        {
            return base[key];
        }
        set
        {
            base[key] = value;
        }
    }
}

现在,我想创建一个实例并添加一些内容。 以下工作正常,即我可以在索引器的setter中设置断点,它将被命中。

MyDictionary<int, string> dict = new MyDictionary<int, string>();
dict[0] = "some value";

但是,如果我这样做(实例化为IDictionary变量):

IDictionary<int, string> dict = new MyDictionary<int, string>();
dict[0] = "some value";

它将不再在索引器的setter中击中我的断点,即它必须调用其他东西。如果我看一下.NET的Dictionary实现(我的类继承),我找不到其他索引器而不是我覆盖的索引器,并且它不会从其他任何东西继承。 所以问题是,发生了什么?

1 个答案:

答案 0 :(得分:11)

该点位于索引器声明中的new关键字中。这不会覆盖基类索引器,并且每次从基类或接口访问索引器时(如示例中的IDictionary) - 都会调用基类的索引器。此外,您无法覆盖基类索引器,因为它在virtual类定义中未标记为Dictionary<TKey, TValue>

在方法声明

中考虑new modifier上的这篇文章

尝试在此处使用合成,而不是继承。

如果您确定,您需要完全IDictionary<TKey, TValue而不是更多抽象接口的自定义行为,例如ICollection<KeyValuePair<TKey, TValue>>甚至IEnumerable<KeyValuePair<TKey, TValue>>,请使用下一个示例:

public class MyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
    IDictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();

    //LOTS of other methods here, that are required by IDictionary<TKey, TValue>
    //their implementation would be delegation to dictionary instance

    public TValue this[TKey key] //implementation of a interface
    {
        get
        {
            return dictionary[key];
        }
        set
        {
            dictionary[key] = value;
        }
    }
}