【问题标题】:Strange behavior of indexer in custom Dictionary自定义字典中索引器的奇怪行为
【发布时间】:2013-03-22 13:28:27
【问题描述】:

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

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

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

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";

它将不再在索引器的设置器中命中我的断点,即它必须调用其他东西。如果我看一下 .NET 的 Dictionary 实现(我的类从它继承),除了我覆盖的那个之外,我找不到其他索引器,而且它不会从其他任何东西继承。 那么问题来了,这是怎么回事?

【问题讨论】:

标签: c# generics dictionary


【解决方案1】:

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

在方法声明中考虑这篇关于new modifier 的文章

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

如果您确定您需要完全针对 IDictionary&lt;TKey, TValue 而不是更抽象的接口(例如 ICollection&lt;KeyValuePair&lt;TKey, TValue&gt;&gt; 甚至 IEnumerable&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;)的自定义行为,请使用下一个示例:

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;
        }
    }
}

【讨论】:

  • @Jodha 抱歉,我正在尝试搜索 msdn,构建一个组合示例,修复拼写,回答此评论以及所有并行操作
  • 写完这个问题后,我突然想到它会是这样的(它称为基本索引器)。然后我有了在派生类中显式实现 IDictionary 接口的想法。这实际上解决了问题。但我认为你关于使用组合的建议可能是一个更好的主意。
  • 因为您不需要重新实现 Dictionary 中定义的 LOTS 功能,您只想委托给它,隐藏您使用具体 @987654331 的事实@内部实现
  • 哦,为了澄清我的评论,我的意思是这样做:public class MyDictionary : Dictionary, IDictionary
  • @maze_dk 不错的解决方案,但有一个缺点 - 如果您的引用类型为 Dictionary - 将调用基类索引器。如果你引用 vid IDictionary 就可以了
猜你喜欢
  • 2012-04-22
  • 2014-11-29
  • 2014-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-26
  • 1970-01-01
相关资源
最近更新 更多