Господа знатоки .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);
}
Здравствуйте, teapot2, Вы писали:
T>Повторяю вопрос: как мне доопределить мой класс myDictionary, содержащий внутри себя массив, чтобы вот этот код компилировался и работал корректно:
T>T>foreach (var item in myDictionary)
T>{
T> Console.WriteLine(item.Key + "=" + item.Value);
T>}
T>
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{
foreach (var item in dict)
{
yield return item;
}
}
Здравствуйте, teapot2, Вы писали:
T>Хорошо, пробуем перейти к обобщенным интерфейсам в определении класса:
T>T>internal class MyDictionary
T>{
T>....
T> public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
T> {
T> return (IEnumerator<KeyValuePair<string, string>>) dict.GetEnumerator();
T> }
T>}
T>
Только нужно писать так:
internal class MyDictionary : IEnumerable<KeyValuePair<string, string>>
{
....
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{
return ((IEnumerable<KeyValuePair<string, string>>) dict).GetEnumerator();
}
}