С# наследует словарь, перебирает 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)
//...