189 votes

Y a-t-il un dictionnaire générique inaltérable disponible dans .NET ?

Je retourne une référence à un dictionnaire dans ma propriété en lecture seule. Comment prévenir les consommateurs de modifier mes données ? Si c’était un je pourrais simplement le retourner . Y a-t-il quelque chose de similaire, que je peux faire avec un dictionnaire ?

230voto

Jeff Yates Points 36725

.NET 4.5

L' .NET Framework 4.5 BCL introduit ReadOnlyDictionary<TKey, TValue> (source).

Comme l' .NET Framework 4.5 BCL ne comprend pas d' AsReadOnly pour les dictionnaires, vous aurez besoin d'écrire votre propre (si vous le voulez). Il serait quelque chose comme ce qui suit, la simplicité de ce qui peut-être explique pourquoi ce n'était pas une priorité pour .NET 4.5.

public static ReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(
    this IDictionary<TKey, TValue> dictionary)
{
    return new ReadOnlyDictionary<TKey, TValue>(dictionary);
}

.NET 4.0 et ci-dessous

Avant .NET 4.5, il n'est pas .NET framework classe qui encapsule une Dictionary<TKey, TValue> comme le ReadOnlyCollection enroule une Liste. Cependant, il n'est pas difficile d'en créer un.

Voici un exemple - il y a beaucoup d'autres si vous Google pour ReadOnlyDictionary.

157voto

Thomas Levesque Points 141081

Voici une implémentation simple qui encapsule un dictionnaire :

20voto

knocte Points 4320

Il a été annoncé lors de la récente conférence BUILD qui depuis .NET 4.5, l'interface System.Collections.Generic.IReadOnlyDictionary<TKey,TValue> est inclus. La preuve en est ici (Mono) et ici (Microsoft) ;)

Vous ne savez pas si ReadOnlyDictionary est incluse trop, mais au moins avec l'interface, il ne devrait pas être difficile de créer maintenant une mise en œuvre qui expose un officiel .NET interface générique :)

18voto

Dale Barnard Points 389

N’hésitez pas à utiliser mon wrapper simple. Il n’implémente pas de IDictionary, donc il ne doit pas lever d’exceptions lors de l’exécution pour les méthodes de dictionnaire qui allait changer le dictionnaire. Méthodes de changement tout simplement ne sont pas là. J’ai fait mon propre interface pour qu’on appelle IReadOnlyDictionary.

11voto

Neal Points 2286

IsReadOnly sur IDictionary<TKey,TValue> est hérité de l' ICollection<T> (IDictionary<TKey,TValue> s'étend ICollection<T> comme ICollection<KeyValuePair<TKey,TValue>>). Il n'est pas utilisé ou mis en œuvre dans tous les sens ( et est en fait "caché" par le biais de l'utilisation de explicitement la mise en œuvre de la associée ICollection<T> des membres ).

Il y a au moins 3 façons je peux voir à résoudre le problème:

  1. Mettre en œuvre une coutume de lire seulement IDictionary<TKey, TValue>et wrap / déléguer à un intérieur dictionnaire comme cela a été suggéré
  2. De retour d'un ICollection<KeyValuePair<TKey, TValue>> en lecture seule ou un IEnumerable<KeyValuePair<TKey, TValue>> selon l'utilisation de la valeur
  3. Clone le dictionnaire à l'aide de la copie constructeur .ctor(IDictionary<TKey, TValue>) et retourner une copie qui façon dont l'utilisateur est libre d'en faire ce comme ils s'il vous plaît et il n'a pas impact sur l'état de l'objet l'hébergement du dictionnaire source. Note que si le dictionnaire le clonage contient les types de référence ( pas de chaînes comme indiqué dans l'exemple ) vous aurez besoin de faire la copie "manuellement", et le clone de référence types ainsi.

Comme un de côté; quand on expose des collections, ont pour objectif d'exposer le plus possible à l'interface dans le cas de l'exemple, il devrait être IDictionary que cela vous permet de varier l'implémentation sous-jacente sans rompre le contrat public que le type expose.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X