J'ai souvent des cours exposant des listes comme Quelle est la meilleure façon de le faire pour un "code> igr orthictionnel lisonlycollection sortedlist
3 Réponses :
Créer une classe lisonlydictionner qui implémente la natricication en tant que wrapper autour d'une instance de dictionnaire interne. Pour les méthodes qui modifieraient le dictionnaire, lancez une exception. Mettre en œuvre isreadonly pour retourner vrai. Implémenter toutes les autres méthodes pour passer à l'instance de dictionnaire interne. P>
Je pense que jeter une exception n'est pas une bonne idée, car c'est un événement d'exécution.
Je recommanderais également de fabriquer IsReadonly et les méthodes de modification des méthodes de mise en œuvre d'interface explicite pour correspondre à ReadonlyCollection: Igrat Bool TVALUE ITRICTION
@zerkms: Readonlycollection lance NotSupportedException ("La collection est en lecture seule.") code> sur ses implémentations explicites.
@Simon Buchan: Oui, et ce n'est pas un chèque statique.
public class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
private readonly IDictionary<TKey, TValue> sourceDictionary;
public ICollection<TKey> Keys
{
get { return sourceDictionary.Keys; }
}
public ICollection<TValue> Values
{
get { return sourceDictionary.Values; }
}
public TValue this[TKey key]
{
get { return sourceDictionary[key]; }
set { throw new NotSupportedException(); }
}
public int Count
{
get { return sourceDictionary.Count; }
}
public bool IsReadOnly
{
get { return true; }
}
public ReadOnlyDictionary(IDictionary<TKey, TValue> sourceDictionary)
{
AssertUtilities.ArgumentNotNull(sourceDictionary, "sourceDictionary");
this.sourceDictionary = sourceDictionary;
}
void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
{
throw new NotSupportedException();
}
public bool ContainsKey(TKey key)
{
return sourceDictionary.ContainsKey(key);
}
bool IDictionary<TKey, TValue>.Remove(TKey key)
{
throw new NotSupportedException();
}
public bool TryGetValue(TKey key, out TValue value)
{
return sourceDictionary.TryGetValue(key, out value);
}
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
{
throw new NotSupportedException();
}
void ICollection<KeyValuePair<TKey, TValue>>.Clear()
{
throw new NotSupportedException();
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return sourceDictionary.Contains(item);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
sourceDictionary.CopyTo(array, arrayIndex);
}
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
{
throw new NotSupportedException();
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return sourceDictionary.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)sourceDictionary).GetEnumerator();
}
}
[Edit]
@Simon Buchan and @Cory Nelson pointed out that it is better to use implicit interface implementation for those methods that are not supported. Updated the code accordingly.
Cheers, je pense que je vais faire cela avec la modification de l'héritage de logeonlycollection
@Matthew Finlay - Je suggère de ne pas faire cela. Vous perdrez la puissance du dictionnaire, comme une recherche optimisée.
@Alex, juste curieux, pourquoi incluez-vous ajouter () / Supprimer () / Effacer () CODE> et jette les NSE? Pourquoi ne pas simplement les laisser tous ensemble?
@JB - Si vous avez des usages qu'en cas d'accident, utilisez ces méthodes, vous préférez préférer cracer afin que vous sachiez sur le bogue, plutôt que d'avoir des bugs subtils.
Vous devriez faire les méthodes non supportées privées.
@Cory - Sérieusement? :) Ces méthodes font partie de l'interface de TValue TValue> TValue>. Pouvez-vous me montrer comment faire ces méthodes privées? Je voudrais vraiment savoir.
De la même manière que vous avez fabriquée iEnumerable.getenumerator () privée.
@Cory - Getenumerator Ce n'est pas privé. C'est une implémentation explicite de l'interface. Rien n'empêche quiconque d'appeler GetenileAutorator.
Rien n'empêche les gens de l'appeler, mais ils doivent l'appeler à travers iEnumerable. En utilisant directement la classe, la méthode ne sera pas disponible.
@Cory - Si vous dites qu'il est préférable d'utiliser une implémentation d'interface explicite dans ce cas, je suis d'accord. Vous avez dit de le faire privé - cela n'avait pas de sens pour moi.
@Simon Buchan - Je suis d'accord avec ça, et j'ai dit cela dans mon dernier message :). Mettra à jour la réponse pour rendre tous les gens heureux.
@Alex: Nitpicking - Les membres explicitement mis en œuvre sont en fait privés selon les spécifications. Vérifiez avec Type.getMethods (BindingFlags.Instance | BindingFlags.nonPublic) Code>. Edit: Ouais, je n'ai pas rafraîchi et vois ces commentaires, désolé.
Vous pouvez le faire avec des méthodes standard LINQ.
Créez votre liste de sources: P>
public IReadOnlyDictionary MemberDictionary { get; private set; );
// ...somewhere in your constructor or class's initialization method...
this.MemberDictionary = mySortedDictionary;
Project Votre liste dans un dictionnaire utilisant .toDictionary code> méthode d'extension LINQ: p>
var mySortedDictionary = new SortedDictionary<string, string>(myDictionary);
Les interfaces n'ont rien à voir avec la mise en œuvre.
IDINCTIONNAIRE CODE> Fournit des méthodes d'écriture par définition. Donc, vous ne pouvez tout simplement pas les supprimer.