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

本文关键字:字典 索引 自定义 | 更新日期: 2023-09-27 18:05:23

我创建了一个继承自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<int, string> dict = new MyDictionary<int, string>();
dict[0] = "some value";

它将不再击中我的断点在索引器的setter,也就是说,它必须调用别的东西。如果我看一下。net的Dictionary实现(我的类继承自它),除了我重写的索引器之外,我找不到其他索引器,而且它不继承任何其他索引器。问题是,这是怎么回事?

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

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

考虑这篇关于方法声明中的新修饰符的文章

尝试在这里使用复合,而不是继承。

如果你确定你需要的是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;
        }
    }
}