Solution plus moderne
À moins que vous n'ayez besoin que la collection interne soit modifiable, vous pouvez utiliser le System.Collections.Immutable
package, changer votre type de champ pour être une collection immuable, puis l'exposer directement - en supposant qu'elle Foo
est immuable, bien sûr.
Réponse mise à jour pour répondre plus directement à la question
Existe-t-il une raison d'exposer une collection interne en tant que ReadOnlyCollection plutôt que IEnumerable si le code appelant n'itère que sur la collection?
Cela dépend de la confiance que vous accordez au code d'appel. Si vous avez un contrôle total sur tout ce qui appellera ce membre et que vous garantissez qu'aucun code ne l'utilisera jamais:
ICollection<Foo> evil = (ICollection<Foo>) bar.Foos;
evil.Add(...);
alors bien sûr, aucun mal ne sera fait si vous retournez simplement la collection directement. J'essaye généralement d'être un peu plus paranoïaque que ça.
De même, comme vous le dites: si vous avez seulement besoin IEnumerable<T>
, alors pourquoi vous attacher à quelque chose de plus fort?
Réponse originale
Si vous utilisez .NET 3.5, vous pouvez éviter de faire une copie et éviter le cast simple en utilisant un simple appel à Skip:
public IEnumerable<Foo> Foos {
get { return foos.Skip(0); }
}
(Il existe de nombreuses autres options pour encapsuler trivialement - la bonne chose à propos Skip
de Select / Where est qu'il n'y a pas de délégué à exécuter inutilement pour chaque itération.)
Si vous n'utilisez pas .NET 3.5, vous pouvez écrire un wrapper très simple pour faire la même chose:
public static IEnumerable<T> Wrapper<T>(IEnumerable<T> source)
{
foreach (T element in source)
{
yield return element;
}
}
ReadOnlyCollection
si vous êtes paranoïaque, mais maintenant vous n'êtes pas lié à une implémentation spécifique.