C#继承自Dictionary,迭代KeyValuePairs

C# inherit from Dictionary, iterate over KeyValuePairs

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

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

但失败的原因如下:

Use of keyword 'base' is not valid in this context

在从Dictionary派生的类中,如何迭代实例方法中的KeyValuePair

编辑:我发现我可以执行以下操作:

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

不过,我还是想知道是否有办法通过foreach循环来实现这一点。

编辑:感谢您对不继承Dictionary的建议。我在执行System.Collections.IEnumerable, ICollection>, IEnumerable>, IDictionary


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

除此之外,在您的特定情况下,您要做的是:

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

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


我同意Jaredpar的评论,认为这不是一个好主意。您可能不想公开向外部世界公开字典的所有方法,所以只需将字典设置为私有成员变量,然后提供自己的接口即可。

有了这句话,你要做的就是:

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


Dictionary封装为自定义class MyDictionary中的复合字段,并为myDictionary实现自定义的ienumerable和ienumerator(或其变体)(或生成一种方法,该方法实现了方便的c yield关键字来生成项)。

例如。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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)...

这样可以保持外部方法的封装。您仍然可以从内部或外部迭代类似的实例:

1
2
3
4
5
6
7
8
9
// 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)
        //...