Pourquoi utiliser ImmutableList sur ReadOnlyCollection?

.NET 4.5 a un nouvel espace de noms System.Collections.Immutable

Ce package fournit des collections qui sont thread-safe et ne changent jamais leur contenu, également appelées collections immuables.

Je suis confus. Le problème de sécurité des threads n’est-il pas déjà résolu par la classe ReadOnlyCollection ? Pourquoi utiliser ImmutableList à la place?


Je sais qu’il y a aussi une interface IReadOnlyList . Cela ne résout pas implicitement le problème de la sécurité des threads, car d’autres threads peuvent modifier l’object par une autre interface.

Avec une ReadOnlyCollection :

Une collection en lecture seule est simplement une collection avec un wrapper qui empêche de modifier la collection; Par conséquent, si des modifications sont apscopes à la collection sous-jacente, la collection en lecture seule reflète ces modifications.

Cela ne peut pas arriver avec une ImmutableList .

ReadOnlyCollection ne résout aucun des problèmes de sécurité des threads. C’est simplement un wrapper autour de Ilist . Il n’expose pas les membres pour modifier la collection, mais vous pouvez toujours la modifier avec la référence de collection sous-jacente.

Si la collection sous-jacente est modifiée, il n’est pas sûr d’énumérer le ReadOnlyCollection . Si vous le faites, vous obtiendrez la même InvalidOperationException avec le message “Collection a été modifiée; l’opération d’énumération peut ne pas s’exécuter …”.

De ReadOnlyCollection

Un ReadOnlyCollection peut prendre en charge plusieurs lecteurs simultanément, à condition que la collection ne soit pas modifiée. Cependant, l’énumération via une collection n’est pas insortingnsèquement une procédure sécurisée pour les threads. Pour garantir la sécurité des threads pendant l’énumération, vous pouvez verrouiller la collection pendant toute l’énumération. Pour permettre à la collection d’être accessible par plusieurs threads pour la lecture et l’écriture, vous devez implémenter votre propre synchronisation.

ImmutableList est quant à lui immuable et donc insortingnsèquement sûr.

ReadOnlyCollection , comme son nom l’indique, ne peut être lu que

D’un autre côté, vous pouvez append / supprimer des éléments vers / depuis un ImmutableList en appelant ses méthodes Add / Remove / Clear , par exemple, qui renvoient une nouvelle liste immuable.

Dans les scénarios multithread, sachez que les collections en lecture seule ne sont toujours pas compatibles avec les threads.

De la documentation ReadOnlyCollection :

… si des modifications sont apscopes à la collection sous-jacente, la collection en lecture seule reflète ces modifications

Étant donné que les collections, telles que List et autres, ne sont pas sûres, la collection en lecture seule ne l’est pas.

Important : il existe des cas en coin que vous ne trouverez pas explicitement expliqués dans MSDN. Certaines des opérations qui, apparemment, ne lisent que le contenu d’une collection, modifient en fait les structures internes de la collection. Pourquoi n’est-ce pas spécifié? – Une raison évidente est que c’est un détail d’implémentation qui ne se reflète pas dans l’API. Le résultat est que même si vous ne modifiez pas la List encapsulée dans un ReadOnlyCollection , et n’utilisez que des getters, le crash pourrait toujours se produire dans un environnement multithread!

En fin de compte, les collections communes, même si elles sont intégrées à un ReadOnlyCollection ne peuvent pas être utilisées dans un environnement multithread prêt à l’emploi.

Contrairement à ReadOnlyCollection , les collections immuables garantissent qu’aucune des structures internes ne changera une fois qu’une référence à une collection aura été obtenue. Notez que ces structures ne sont toujours pas immuables. Ils sont plutôt gelables . Cela signifie que la structure changera en interne pendant un certain temps jusqu’à ce qu’elle soit gelée et renvoyée à l’appelant. Au-delà de ce point, tous les autres appels de la collection immuable ne feront que des modifications en dehors des structures accessibles via la référence d’origine.

Conclusion: les collections en lecture seule ne sont pas compatibles avec les threads; les collections immuables sont sécurisées pour les threads.