У вас не будет для реализации IEnumerable<T>
или IEnumerable
, чтобы заставить foreach
работать - но было бы неплохо сделать это.Это очень легко сделать:
public class Foo : IEnumerable<Bar>
{
public IEnumerator<Bar> GetEnumerator()
{
// Use yield return here, or
// just return Values.GetEnumerator()
}
// Explicit interface implementation for non-generic
// interface; delegates to generic implementation.
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Альтернатива, которую не реализует IEnumerable<T>
, просто вызовет ваше свойство Values
, но при этом предоставит метод GetEnumerator()
:
public class Foo
{
public IEnumerator<Bar> GetEnumerator()
{
// Use yield return here, or
// just return Values.GetEnumerator()
}
]
Хотя это будет работать, это означает, что вы не сможете передать свою коллекцию чему-либо, ожидающему IEnumerable<T>
, например LINQ to Objects.
Это малоизвестныйтот факт, что foreach
будет работать с любым типом, поддерживающим метод GetEnumerator()
, который возвращает тип с соответствующими MoveNext()
и Current
членами.Это было сделано для того, чтобы разрешить строго типизированные коллекции перед генериками, где итерация по коллекции не будет блокировать типы значений и т. Д. Сейчас это действительно не нужно, IMO.