Bardziej nowoczesne rozwiązanie
O ile nie potrzebujesz, aby kolekcja wewnętrzna była zmienna, możesz użyć System.Collections.Immutablepakietu, zmienić typ pola na niezmienną kolekcję, a następnie ujawnić to bezpośrednio - Foooczywiście zakładając , że jest niezmienny.
Zaktualizowana odpowiedź, aby bardziej bezpośrednio odpowiedzieć na pytanie
Czy istnieje jakiś powód, aby uwidaczniać kolekcję wewnętrzną jako ReadOnlyCollection, a nie IEnumerable, jeśli kod wywołujący wykonuje iterację tylko po kolekcji?
To zależy od tego, jak bardzo ufasz kodowi dzwoniącemu. Jeśli masz pełną kontrolę nad wszystkim, co kiedykolwiek zadzwoni do tego członka i gwarantujesz, że żaden kod nigdy nie użyje:
ICollection<Foo> evil = (ICollection<Foo>) bar.Foos;
evil.Add(...);
to z pewnością nic się nie stanie, jeśli po prostu zwrócisz kolekcję bezpośrednio. Jednak generalnie staram się być trochę bardziej paranoikiem.
Podobnie, jak mówisz: jeśli tylko potrzebujesz IEnumerable<T> , to po co przywiązywać się do czegoś mocniejszego?
Oryginalna odpowiedź
Jeśli używasz .NET 3.5, możesz uniknąć tworzenia kopii i prostego rzutowania, używając prostego wywołania Skip:
public IEnumerable<Foo> Foos {
get { return foos.Skip(0); }
}
(Istnieje wiele innych opcji zawijania w trywialny sposób - fajną rzeczą Skipw przypadku opcji Select / Where jest to, że nie ma delegata do bezcelowego wykonywania dla każdej iteracji).
Jeśli nie używasz .NET 3.5, możesz napisać bardzo prosty wrapper, który zrobi to samo:
public static IEnumerable<T> Wrapper<T>(IEnumerable<T> source)
{
foreach (T element in source)
{
yield return element;
}
}
ReadOnlyCollectionjeśli masz paranoję, ale teraz nie jesteś przywiązany do konkretnej implementacji.