foreach(var item in ...) и Энумераторы
От: teapot2  
Дата: 04.12.13 11:06
Оценка:
Господа знатоки .net и C#, подскажите, пожалуйста, как мне сделать правильно вот такую вещь:

Есть некий класс, содержащий внутри себя массив некотрых объектов. Хочу, чтобы оператор foreach с объектом этого класса был идентичен (со всеми синтаксическими деталями, т.е. с возможностью использования var в заголовке цикла) аналогичному оператору с содержащимся внутри него массивом.

Поясняю:

Скажем, есть класс, внутрь которого запрятан массив KeyValuePair<string, string>:
internal class MyDictionary
{
    private KeyValuePair<string, string>[] dict;
    public MyDictionary(KeyValuePair<string, string>[] dict)
    {
        this.dict = dict.ToArray();
    }
...
}

Я хочу, чтобы с объектом этого класса (точно так же, как и с содержащимся внутри него массивом) можно было сделать примерно так:
foreach (var item in myDictionary) 
{
    Console.WriteLine(item.Key + "=" + item.Value);
}


Насколько я понимаю, надо в моем классе определить энумератор. ОК. Определяю, получается вот что:
internal class MyDictionary
{
    private KeyValuePair<string, string>[] dict;
    public MyDictionary(KeyValuePair<string, string>[] dict)
    {
        this.dict = dict.ToArray();
    }
    public IEnumerator GetEnumerator()
    {
        return dict.GetEnumerator();
    }
}


Это работает не совсем так, как хотелось бы. То есть приведенный в предыдущем примере foreach не компилируется, пишет, что у объекта класса Object нет свойств Key и Value.
Приходится внутри заголовка foreach явно указывать тип элементов массива. Так работает, но это не совсем то, чего хотелось:
foreach (KeyValuePair<string, string> item in myDictionary) 
{
    Console.WriteLine(item.Key + "=" + item.Value);
}


Хорошо, пробуем перейти к обобщенным интерфейсам в определении класса:
internal class MyDictionary
{
....
    public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
    {
        return (IEnumerator<KeyValuePair<string, string>>) dict.GetEnumerator();
    }
}


Так все компилируется, но при попытке foreach бросается исключение невалидного кастования, что вполне понятно:

System.InvalidCastException: Unable to cast object of type 'SZArrayEnumerator' to type 'System.Collections.Generic.IEnumerator`1[System.Collections.Generic.KeyValuePair`2[System.String,System.String]]'.


Повторяю вопрос: как мне доопределить мой класс myDictionary, содержащий внутри себя массив, чтобы вот этот код компилировался и работал корректно:
foreach (var item in myDictionary) 
{
    Console.WriteLine(item.Key + "=" + item.Value);
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.