2010-03-03 2 views
3

L'interface IList<T> inclut l'accès par index en plus des opérations non prises en charge par la propriété SortedList<TKey, TValue>.Keys telles que Add, Remove et Insert.Pourquoi la propriété SortedList (TKey, TValue) .Keys est-elle un IList (TKey) plutôt qu'une ReadOnlyCollection (TKey)?

A ReadOnlyCollection<T>, comme la valeur de retour de List<T>.AsReadOnly, met en œuvre IList<T> et offre donc un accès par index mais cache des opérations illégales comme Add, etc. en les appliquant explicitement. En outre, il s'agit simplement d'un wrapper pour la liste sous-jacente; donc il ne crée pas de copie et devrait donc (je suppose) ne subir aucun véritable coup de performance.

Une idée pourquoi SortedList<TKey, TValue.Keys n'est pas un ReadOnlyCollection<TKey>? (Et d'ailleurs pourquoi la propriété Values n'est pas un ReadOnlyColllection<TValue>?)

+0

Il est étrange qu'il ne soit pas readonly collection, car si vous faites triedList.Values.Add (2); il jette l'exception – Andrey

+0

Exactement! Très curieux ... –

+0

Je pense que la raison est que ReadOnlyCollection est classe non interface. Avec l'interface, vous pouvez écrire un stockage personnalisé, mais ReadOnlyCollection a son propre – Andrey

Répondre

3

Ceci est assez obscur, mais je pense que c'est une optimisation. Cela a quelque chose à voir avec la façon dont les génériques sont mis en œuvre. Le code machine d'une méthode de classe générique est créé lors de l'exécution par le compilateur JIT. Il doit en faire plusieurs versions concrètes. Il y en a un pour tout type de référence. Et un chacun pour chaque argument de type valeur unique utilisé dans un programme.

Cela peut être inefficace, potentiellement beaucoup de code qui doit être généré. Particulièrement mauvais pour les classes de framework génériques, ils sont Ngen-ed. L'implémentation de la méthode concrète devrait être compilée par JIT et ne pourrait pas être dans l'image de Ngen.

Pour lutter contre cela, il y a du code privé dans le framework (désolé, j'ai oublié où), qui instancie toute une série de différentes versions de classes génériques. Intéressant code de do-rien, il m'a intrigué pendant un bon moment. Mais l'effet secondaire est que Ngen.exe génère du code pour les méthodes de classe génériques. Si vous utilisez maintenant une telle classe générique dans votre propre code, vous obtiendrez l'implémentation concrète de la méthode à partir de l'image Ngen, le compilateur JIT n'est pas nécessaire.

Vous pouvez voir où cela conduit, System.Collections.ObjectModel.ReadOnlyCollection a probablement été jugé trop obscur pour être inclus dans cette liste. Facilement vérifiable, vous verrez que lorsque vous faites un pas en un seul si ses méthodes, vous n'interviendra pas dans le code source, même si vous avez le .pdbs Source de référence.

Je ne suis pas sûr à 100% que ce soit l'explication exacte. Mais la chaussure s'adapte.

+0

Très intéressante, réponse très utile. J'espérais quelque chose en profondeur comme ça. Maintenant, je vais creuser autour de moi pour ce dont vous parlez. –

Questions connexes