Dictionnaire en lecture seule en C#
J'ai un Dictionary<string, List<string>>
et tenons à exposer le membre comme étant en lecture seule. Je vois que je peux le retourner comme un IReadOnlyDictionary<string, List<string>>
, mais je ne peux pas comprendre comment le retourner comme un IReadOnlyDictionary<string, IReadOnlyList<string>>
.
Est-il un moyen de faire cela? En c++, je venais d'utilisation de const, mais le C# n'a pas que.
Remarque que, tout simplement, à l'aide d'un IReadOnlyDictionary
n'aide pas dans ce cas, parce que je veux le lire les valeurs de seulement ainsi. Il semble que la seule façon de le faire est de construire un autre IReadOnlyDictionary, et ajouter IReadOnlyList à eux.
Une autre option, qui je ne serais pas heureux avec, serait de créer un wrapper qui implémente l'interface IReadOnlyDictionary>, et de conserver une copie de l'instance d'origine, mais qui semble exagéré.
- À propos d'une recherche à la place? Le Dictionnaire d'objet a la
ToLookup()
extension. msdn.microsoft.com/en-us/library/bb460184(v=vs. 110).aspx - Double Possible de Comment utiliser correctement IReadOnlyDictionary?
- Double Possible de Est-il en lecture seule dictionnaire générique disponible dans .NET?
Vous devez vous connecter pour publier un commentaire.
Il serait aussi facile que de moulage de l'ensemble du dictionnaire de référence de
IReadOnlyDictionary<string, IReadOnlyList<string>>
parce queDictionary<TKey, TValue>
implémenteIReadOnlyDictionary<TKey, TValue>
.BTW, vous ne pouvez pas le faire parce que vous voulez que le
List<string>
valeursIReadOnlyList<string>
.De sorte que vous besoin de quelque chose comme ceci:
Immuable dictionnaires
C'est juste une suggestion, mais si vous êtes à la recherche d'immuable dictionnaires, ajouter
System.Les Collections.Immuable
package NuGet à votre solution et vous serez en mesure de les utiliser:En savoir plus sur Immuable des Collections ici.
Compte tenu du fait que vous êtes spécifiquement à la recherche d'une lecture seule
Dictionary<string, List<string>>
, vous êtes essentiellement à la recherche exactement pour un Recherche.Le Dictionnaire d'objet a un
ToLookup()
extension.A Lookup<TKey,TElement> resembles a Dictionary<TKey,TValue>. The difference is that a Dictionary<TKey,TValue> maps keys to single values, whereas a Lookup<TKey,TElement> maps keys to collections of values.
List<string>
, de sorte que la recherche fonctionne parfaitement.Tout d'abord, vous devrez créer un nouveau dictionnaire avec les types de contenu:
Alors vous pouvez simplement retourner le nouveau dictionnaire, depuis
IReadOnlyDictionary
est un supertype deDictionary
.Pourquoi avez-vous besoin de faire cela? Parce que
Dictionary<T, A>
n'est pas un supertype deDictionary<T, B>
, même siA
est un supertype deB
. Pourquoi? Considérons l'exemple suivant:En d'autres termes,
TValue
dansDictionary
n'est pas covariante. À partir d'un objet-orientied point de vue, la covariance devrait être possible en lecture seule version du dictionnaire, mais il y a des problèmes de succession dans la .NET framework qui empêchent ce phénomène (voir la partie commençant par "mise à JOUR" dans cette question pour plus de détails).TValue
ne peut pas être covariants, mais dans ce cas je crois queList<string>
estIReadOnlyList<string>
. Ce n'est pas exactementA
etB
.Dictionary
n'auraient pas besoin d'être covariantes à l'égard deTValue
, **IReadOnlyDictionary
aurait besoin d'être covariantes à l'égard deTValue
.IDictionary
, pasIReadOnlyDictionary
.IReadOnlyDictionary<TKey, TValue>
dans .NET 4.5, mais il ne sera pas covariante, soit :·/, parce qu'il dérive deIEnumerable<KeyValuePair<TKey, TValue>>
, etKeyValuePair<TKey, TValue>
n'est pas une interface, et donc ne peut pas être covariantes."Si vous voulez retourner à la lecture seulement, dictionnaire mais encore être capable de muter le dictionnaire et la liste dans votre classe, vous pouvez utiliser un casting pour récupérer la liste type.
Cet exemple est un peu tiré par les cheveux, mais de montrer comment cela pourrait fonctionner.
Si votre objectif est d'avoir la propriété d'être immuable, puis à l'aide d'un ReadOnlyDictionary serait la meilleure option.
https://msdn.microsoft.com/en-us/library/acdd6hb7.aspx
Vous pouvez l'utiliser pour exposer l'objet en readonly.
Vous pouvez également utiliser les propriétés get; set; et d'autoriser uniquement la chance d'être public.
Mais Matias réponse semble être plus adaptée.
.Add()
ou.Remove()