Bardziej nowoczesne rozwiązanie
O ile nie potrzebujesz, aby kolekcja wewnętrzna była zmienna, możesz użyć System.Collections.Immutable
pakietu, zmienić typ pola na niezmienną kolekcję, a następnie ujawnić to bezpośrednio - Foo
oczywiś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ą Skip
w 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;
}
}
ReadOnlyCollection
jeśli masz paranoję, ale teraz nie jesteś przywiązany do konkretnej implementacji.