С# наследует словарь, перебирает KeyValuePairs

У меня есть класс, который наследуется от Dictionary<string, string>. Внутри метода экземпляра я хочу перебрать все KeyValuePair<string, string>. Я пробовал сделать следующее:

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

Но это не выполняется со следующей ошибкой:

Использование ключевого слова 'base' недопустимо в этом контексте

Как я могу перебирать KeyValuePair<string, string> в методе экземпляра в классе, который происходит от Dictionary<string, string>?

Изменить: Я нашел, что могу сделать следующее:

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

Однако мне все равно хотелось бы узнать, есть ли способ сделать это с помощью цикла foreach.

Изменить: спасибо за советы о не наследовании от Dictionary<string, string>. Вместо этого я использую System.Collections.IEnumerable, ICollection<KeyValuePair<string, string>>, IEnumerable<KeyValuePair<string, string>>, IDictionary<string, string>.

Ответы

Ответ 1

Во-первых, вывод из классов коллекции .NET обычно не рекомендуется, поскольку они не предлагают виртуальные методы для вызовов, не унаследованных от object. Это может привести к ошибкам при передаче вашей производной коллекции через ссылку на базовый класс. Вам лучше реализовать интерфейс IDictionary<T,TKey> и агрегировать Dictionary<,> внутри вашей реализации, после чего вы переадресовываете соответствующие вызовы.

В стороне, в вашем конкретном случае, вы хотите:

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

Ключевое слово base в основном используется для доступа к определенным членам вашего базового класса. Это не то, что вы здесь делаете - вы пытаетесь перебирать элементы определенного экземпляра... это просто ссылка this.

Ответ 2

Я согласен с комментарием JaredPar, что это не отличная идея. Вероятно, вы не хотите публично публиковать все методы Словаря во внешнем мире, поэтому просто сделайте Словарь частной переменной-членом, а затем предоставите свой собственный интерфейс.

С учетом сказанного, способ сделать то, что вы пытаетесь сделать, это:

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

Ответ 3

Инкапсулировать Dictionary<string, string> как скомпилированное поле внутри пользовательского class MyDictionary и реализовать пользовательский IEnumerable и IEnumerator (или их варианты) для MyDictionary (или сделать метод, который реализует удобный С# 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)
        //...