9 votes

Dictionnaires à touches multiples (d'un autre type) en C# ?

Construire sur cette question existe-t-il une solution simple pour avoir un dictionnaire à plusieurs clés où l'une ou l'autre des touches individuellement peut être utilisé pour identifier la valeur ?

ie.

MultikeyDictionary<TKey1, TKey2, TValue> foo;
foo.Add(key1, key2, value);
myValue = foo[key1];
// value == myValue
foo.Remove(key2);
myValue = foo[key1]; // invalid, Exception or null returned

1voto

Ofir Points 839

J'ai essayé ceci et cela fonctionne parfaitement (inclure add, remove & indexer)

public class MultikeyDictionary<K1, K2, V> : Dictionary<KeyValuePair<K1, K2>, V>
{
    public V this[K1 index1, K2 index2]
    {
        get
        {
            return this[new KeyValuePair<K1, K2>(index1, index2)];
        }
        set
        {
            this[new KeyValuePair<K1, K2>(index1, index2)] = value;
        }
    }

    public bool Remove(K1 index1, K2 index2)
    {
        return base.Remove(new KeyValuePair<K1,K2>(index1, index2));
    }

    public void Add(K1 index1, K2 index2, V value)
    {
        base.Add(new KeyValuePair<K1, K2>(index1, index2), value);
    }
}

et même je l'ai étendu à 4 valeurs :

public class MultikeyDictionary<K1, K2, K3, V> : MultikeyDictionary<KeyValuePair<K1, K2>, K3, V>
{
    public V this[K1 index1, K2 index2, K3 index3]
    {
        get
        {
            return base[new KeyValuePair<K1, K2>(index1, index2), index3];
        }
        set
        {
            base[new KeyValuePair<K1, K2>(index1, index2), index3] = value;
        }
    }

    public bool Remove(K1 index1, K2 index2, K3 index3)
    {
        return base.Remove(new KeyValuePair<K1, K2>(index1, index2), index3);
    }

    public void Add(K1 index1, K2 index2, K3 index3, V value)
    {
        base.Add(new KeyValuePair<K1, K2>(index1, index2), index3, value);
    }
}

Profitez-en,

Ofir

0voto

David B Points 53123

Bien sûr, c'est un langage OO et vous pouvez implémenter tous les O's que vous voulez. Vous allez avoir quelques ambiguïtés à résoudre (que se passe-t-il si TKey1 et TKey2 sont du même type, quelles méthodes sont appelées dans ce cas ?)

0voto

Adam Luter Points 1043

Vous ne pourrez pas définir les surcharges pour les deux types, et le système générique ne permet pas un nombre arbitraire de types (comme les méthodes permettent les paramètres). Ainsi, vous seriez coincé avec un ensemble de classes qui définissent 2, 3, 4, etc. clés simultanées. De plus, il faudrait utiliser l'objet comme paramètre pour get et set, en utilisant des contrôles de type à l'exécution pour simuler la surcharge.

En outre, vous ne stockez qu'un seul dictionnaire de <TKEY1,VAL> les autres dictionnaires seraient de <TKEY2,TKEY1> , <TKEY3,TKEY1> et agiraient comme des index sur le dictionnaire principal.

C'est surtout du code standard.

0voto

Ben Manes Points 1790

Vous pouvez trouver mon IndexMap est une bonne base pour la réécriture de Java en C#. Le modèle de programmation n'est pas aussi élégant que je le souhaiterais, mais il n'est pas destiné à être utilisé directement pour le développement. Il se trouve plutôt derrière une bibliothèque de mise en cache qui fournit des annotations standard pour permettre un style de codage succinct. En utilisant l'interface Map, elle fournit un modèle de composition propre lorsqu'elle est combinée avec des décorateurs de carte auto-populants, expiratoires et évocables. Je suis sûr que quelqu'un pourrait proposer une interface de programmation agréable pour une utilisation directe où il est acceptable de perdre les avantages de l'interface Map.

0voto

Baron Points 123

Ce n'est pas une solution directe et ce n'est pas viable pour les clés multiples, mais cela a fonctionné pour mon cas d'utilisation.

Dictionary<Guid, Object> objs = new Dictionary<Guid, Object>();
Dictionary<int, Guid> guids = new Dictionary<int, Guid>();

private void Set(object sender, Object obj)
{
    objs[obj.Guid] = obj;
    guids[obj.Id] = obj.Guid;
}

public Object Get(int id)
{
    return guids.ContainsKey(id) ? Get(guids[id]) : null;
}

public Object Get(Guid guid)
{
    return objs.ContainsKey(guid) ? objs[guid] : null;
}

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