Maison > développement back-end > C++ > Pourquoi implémenter un OrderedDictionary générique en C# ?

Pourquoi implémenter un OrderedDictionary générique en C# ?

Linda Hamilton
Libérer: 2025-01-01 00:45:09
original
749 Les gens l'ont consulté

Why Implement a Generic OrderedDictionary in C#?

Implémenter un OrderedDictionary générique n'est pas particulièrement difficile, mais cela prend inutilement du temps et franchement, cette classe est un énorme oubli de la part de Microsoft. Il existe plusieurs façons de mettre en œuvre cela, mais j'ai choisi d'utiliser une KeyedCollection pour mon stockage interne. J'ai également choisi d'implémenter diverses méthodes de tri de la manière dont List fait puisqu'il s'agit essentiellement d'un IList et d'un IDictionary hybrides.

Voici l'interface. Notez qu'il inclut System.Collections.Specialized.IOrderedDictionary, qui est la version non générique de cette interface fournie par Microsoft.

// https://choosealicense.com/licenses/unlicense
// ou https://choosealicense.com/licenses/mit/
using System;
using System.Collections.Generic;
using System.Collections.Specialized;

namespace mattmc3.Common.Collections.Generic {

public interface IOrderedDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IOrderedDictionary {
    new TValue this[int index] { get; set; }
    new TValue this[TKey key] { get; set; }
    new int Count { get; }
    new ICollection<TKey> Keys { get; }
    new ICollection<TValue> Values { get; }
    new void Add(TKey key, TValue value);
    new void Clear();
    void Insert(int index, TKey key, TValue value);
    int IndexOf(TKey key);
    bool ContainsValue(TValue value);
    bool ContainsValue(TValue value, IEqualityComparer<TValue> comparer);
    new bool ContainsKey(TKey key);
    new IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator();
    new bool Remove(TKey key);
    new void RemoveAt(int index);
    new bool TryGetValue(TKey key, out TValue value);
    TValue GetValue(TKey key);
    void SetValue(TKey key, TValue value);
    KeyValuePair<TKey, TValue> GetItem(int index);
    void SetItem(int index, TValue value);
}
Copier après la connexion

}
Voici l'implémentation avec l'assistant cours :

// http://unlicense.org
en utilisant System;
en utilisant System.Collections.ObjectModel;
en utilisant System.Diagnostics;
en utilisant System.Collections;
en utilisant System.Collections.Specialized;
en utilisant System.Collections.Generic;
en utilisant System.Linq;

espace de noms mattmc3.Common.Collections.Generic {

/// <summary>
/// A dictionary object that allows rapid hash lookups using keys, but also
/// maintains the key insertion order so that values can be retrieved by
/// key index.
/// </summary>
public class OrderedDictionary<TKey, TValue> : IOrderedDictionary<TKey, TValue> {

    #region Fields/Properties

    private KeyedCollection2<TKey, KeyValuePair<TKey, TValue>> _keyedCollection;

    /// <summary>
    /// Gets or sets the value associated with the specified key.
    /// </summary>
    /// <param name=&quot;key&quot;>The key associated with the value to get or set.</param>
    public TValue this[TKey key] {
        get {
            return GetValue(key);
        }
        set {
            SetValue(key, value);
        }
    }

    /// <summary>
    /// Gets or sets the value at the specified index.
    /// </summary>
    /// <param name=&quot;index&quot;>The index of the value to get or set.</param>
    public TValue this[int index] {
        get {
            return GetItem(index).Value;
        }
        set {
            SetItem(index, value);
        }
    }

    public int Count {
        get { return _keyedCollection.Count; }
    }

    public ICollection<TKey> Keys {
        get {
            return _keyedCollection.Select(x => x.Key).ToList();
        }
    }

    public ICollection<TValue> Values {
        get {
            return _keyedCollection.Select(x => x.Value).ToList();
        }
    }

    public IEqualityComparer<TKey> Comparer {
        get;
        private set;
    }

    #endregion

    #region Constructors

    public OrderedDictionary() {
        Initialize();
    }

    public OrderedDictionary(IEqualityComparer<TKey> comparer) {
        Initialize(comparer);
    }

    public OrderedDictionary(IOrderedDictionary<TKey, TValue> dictionary) {
        Initialize();
        foreach (KeyValuePair<TKey, TValue> pair in dictionary) {
            _keyedCollection.Add(pair);
        }
    }

    public OrderedDictionary(IOrderedDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) {
        Initialize(comparer);
        foreach (KeyValuePair<TKey, TValue> pair in dictionary) {
            _keyedCollection.Add(pair);
        }
    }

    #endregion

    #region Methods

    private void Initialize(IEqualityComparer<TKey> comparer = null) {
        this.Comparer = comparer;
        if (comparer != null) {
            _keyedCollection = new KeyedCollection2<TKey, KeyValuePair<TKey, TValue>>(x => x.Key, comparer);
        }
        else {
            _keyedCollection = new KeyedCollection2<TKey, KeyValuePair<TKey, TValue>>(x => x.Key);
        }
    }

    public void Add(TKey key, TValue value) {
        _keyedCollection.Add(new KeyValuePair<TKey, TValue>(key, value));
    }

    public void Clear() {
        _keyedCollection.Clear();
    }

    public void Insert(int index, TKey key, TValue value) {
        _keyedCollection.Insert(index, new KeyValuePair<TKey, TValue>(key, value));
    }

    public int IndexOf(TKey key) {
        if (_keyedCollection.Contains(key)) {
            return _keyedCollection.IndexOf(_keyedCollection[key]);
        }
        else {
            return -1;
        }
    }

    public bool ContainsValue(TValue value) {
        return this.Values.Contains(value);
    }

    public bool ContainsValue(TValue value, IEqualityComparer<TValue> comparer) {
        return this.Values.Contains(value, comparer);
    }

    public bool ContainsKey(TKey key) {
        return _keyedCollection.Contains(key);
    }

    public KeyValuePair<TKey, TValue> GetItem(int index) {
        if (index < 0 || index >= _keyedCollection.Count) {
            throw new ArgumentException(String.Format(&quot;The index was outside the bounds of the dictionary: {0}&quot;, index));
        }
        return _keyedCollection[index];
    }

    /// <summary>
    /// Sets the value at the index specified.
    /// </summary>
    /// <param name=&quot;index&quot;>The index of the value desired</param>
    /// <param name=&quot;value&quot;>The value to set</param>
    /// <exception cref=&quot;ArgumentOutOfRangeException&quot;>
    /// Thrown when the index specified does not refer to a KeyValuePair in this object
    /// </exception>
    public void SetItem(int index, TValue value) {
        if (index < 0 || index >= _keyedCollection.Count) {
            throw new ArgumentException(&quot;The index is outside the bounds of the dictionary: {0}&quot;.FormatWith(index));
        }
        var kvp = new KeyValuePair<TKey, TValue>(_keyedCollection[index].Key, value);
        _keyedCollection[index] = kvp;
    }

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
        return _keyedCollection.GetEnumerator();
    }

    public bool Remove(TKey key) {
        return _keyedCollection.Remove(key);
    }

    public void RemoveAt(int index
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal