【问题标题】:C# inherit from Dictionary, iterate over KeyValuePairsC# 继承自 Dictionary,迭代 KeyValuePairs
【发布时间】:2011-01-09 07:44:54
【问题描述】:

我有一个继承自 Dictionary<string, string> 的类。在一个实例方法中,我想遍历所有KeyValuePair<string, string>。我尝试过以下操作:

foreach (KeyValuePair<string, string> pair in base)

但这失败并出现以下错误:

在此上下文中使用关键字“base”无效

如何在派生自Dictionary&lt;string, string&gt; 的类的实例方法中迭代KeyValuePair&lt;string, string&gt;

编辑:我发现我可以做到以下几点:

var enumerator = base.GetEnumerator();
while (enumerator.MoveNext())
{
    KeyValuePair<string, string> pair = enumerator.Current;
}

但是,我仍然想知道是否有办法通过foreach 循环来做到这一点。

编辑:感谢关于不要从 Dictionary&lt;string, string&gt; 继承的建议。我改为实现System.Collections.IEnumerable, ICollection&lt;KeyValuePair&lt;string, string&gt;&gt;, IEnumerable&lt;KeyValuePair&lt;string, string&gt;&gt;, IDictionary&lt;string, string&gt;

【问题讨论】:

  • 不要从 Dictionary 派生,它只会导致意想不到的错误。创建一个包装类会更有效。

标签: c# dictionary foreach


【解决方案1】:

首先,从 .NET 集合类派生通常是不明智的,因为它们不为不是从 object 继承的调用提供虚拟方法。当通过某处的基类引用传递派生集合时,这可能会导致错误。您最好实现IDictionary&lt;T,TKey&gt; 接口并在您的实现中聚合一个Dictionary&lt;,&gt; - 然后您将适当的调用转发到该接口。

除此之外,在您的具体情况下,您想要做的是:

foreach( KeyValuePair<string,string> pair in this )  { /* code here */ }

base 关键字主要用于访问基类的特定成员。这不是您在这里所做的 - 您正在尝试迭代特定实例的项目......这只是 this 参考。

【讨论】:

  • 你应该在“不要为大多数调用提供虚拟方法”中使用任何:)。他们“提供”的唯一虚拟调用是从对象继承的调用
  • @JaredPar:我想如果你不考虑继承自 object 的成员和其他一些带有一些虚拟方法的中间类 - 你确实可以这么说。
【解决方案2】:

我同意 JaredPar 的评论,即这不是一个好主意。您可能不想将 Dictionary 的所有方法公开暴露给外界,所以只需将 Dictionary 设为私有成员变量,然后提供您自己的接口即可。

话虽如此,做你想做的事情的方法是:

foreach (KeyValuePair<string, string> pair in this)

【讨论】:

    【解决方案3】:

    Dictionary&lt;string, string&gt; 封装为自定义class MyDictionary 中的组合字段,并为MyDictionary 实现自定义IEnumerableIEnumerator(或其变体)(或创建一个实现方便的C# yield 关键字的方法以生成项目)...

    例如

    class MyDictionary : IEnumerable<KeyValuePair<string,string>> {
        Dictionary<string, string> _dict;
    
        IEnumerator<KeyValuePair<string,string>> GetEnumerator() {
            return new MyEnum(this); // use your enumerator
            // OR simply forget your own implementation and
            return _dict.GetEnumerator();
        } 
    
        class MyEnum : IEnumerator<KeyValuePair<string,string>> {
            internal MyEnum(MyDictionary dict) {
                //... dict
            }
    
            // implemented methods (.MoveNext, .Reset, .Current)...
    

    这维护了无关方法的封装。 而且您仍然可以像这样从内部或外部迭代您的实例:

    // from outside
    MyDictionary mdict = new MyDictionary();
    foreach (KeyValuePair<string, string> kvp in mdict)
        //...
    
    // from inside, assuming: this == MyDictionary instance)
    public void MyDictionaryMethod() {
        foreach (KeyValuePair<string, string> kvp in this)
            //...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-26
      • 2014-07-18
      • 1970-01-01
      相关资源
      最近更新 更多