web-dev-qa-db-fra.com

Liste <T> .AsReadOnly () vs IReadOnlyCollection <T>

List<T> Implémente l'interface IReadOnlyCollection<T> Et fournit la méthode AsReadOnly() qui renvoie ReadOnlyCollection<T> (Qui à son tour implémente IReadOnlyCollection<T>).

Quelle est l'utilisation/la raison de AsReadyOnly()? Son existence sent un ou deux cas Edge où le simple retour de la liste en tant que IReadOnlyCollection<T> N'est tout simplement pas suffisant.

Au début, je pensais que c'était peut-être pour éviter de rejeter le coût, mais il semble que vous pouvez le faire avec l'accessoire Items de ReadOnlyCollection<T>.

BTW. La documentation du type ReadOnlyCollection<T> Indique

Fournit la classe de base pour une collection générique en lecture seule.

qui, dans ma tête, est en conflit avec le fait d'avoir un constructeur décrit comme

Initialise une nouvelle instance de la classe (...) qui est un wrapper en lecture seule autour de la liste spécifiée.

Mise à jour: Je n'ai pas vu que Items de ReadOnlyCollection<T> Est protégé.

39
tymtam

Si vous retournez simplement un List<T> Réel en tant que IReadOnlyList<T>, L'appelant peut toujours simplement le restituer, puis modifier la liste à sa guise. Inversement, l'appel de AsReadOnly() crée un wrapper en lecture seule de la liste, que les consommateurs ne peuvent pas mettre à jour.

Notez que l'encapsuleur en lecture seule reflétera les modifications apportées à la liste sous-jacente, de sorte que le code avec accès à la liste d'origine peut toujours le mettre à jour en sachant que tous les consommateurs de la version en lecture seule verront ces modifications.

49
dlev

Tout d'abord, ce n'est pas que AsReadOnly() a été ajouté parce que IReadOnlyList<T> N'est pas assez bon - IReadOnlyList<T> N'est disponible qu'à partir de .NET 4.5 tandis que la méthode AsReadOnly() existe depuis .NET 2.

Plus important encore: AsReadOnly() et IReadOnlyList<T> Ont des objectifs très différents.

ReadOnlyCollection<T> Est destiné à l'implémentation de modèles d'objets, par exemple des choses comme Dictionary<K,V>.Keys Et Dictionary<K,V>.Values. Il s'agit de scénarios dans lesquels les consommateurs ne devraient pas pouvoir modifier le contenu alors que le producteur le peut. Il fonctionne en tandem avec Collection<T> Qui fournit des crochets au propriétaire pour valider les modifications ou effectuer des effets secondaires lorsque des éléments sont ajoutés.

IReadOnlyList<T> D'autre part est simplement une interface qui fournit une vue en lecture seule de la collection. Les méthodes peuvent l'utiliser pour dire "J'ai besoin d'une collection à accès aléatoire mais je n'ai pas besoin de pouvoir la modifier". Par exemple, une méthode BinarySearch pourrait ressembler à ceci:

public int BinarySearch<T>(IReadOnlyList<T> list, int start, int length);

Afin de rendre cette méthode utile, il est nécessaire de pouvoir passer dans n'importe quelle liste. Forcer à créer des collections de wrapper coûterait trop cher.

24
Immo Landwerth