C # наследовать от словаря, перебрать KeyValuePairs - PullRequest
4 голосов
/ 26 января 2010

У меня есть класс, который наследуется от 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>.

Ответы [ 3 ]

14 голосов
/ 26 января 2010

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

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

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

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

2 голосов
/ 26 января 2010

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

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

foreach (KeyValuePair<string, string> pair in this)
1 голос
/ 26 января 2010

Инкапсулируйте Dictionary<string, string> как составное поле внутри пользовательского class MyDictionary и реализуйте пользовательский IEnumerable и IEnumerator (или его варианты) для MyDictionary (или создайте метод, который реализует удобный C # yield ключевое слово для производства предметов) ...

1012 * Е.Г. *

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)
        //...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...