Per puposes interni ho scritto una BiDictionary
. Non è a prova di proiettile perché non lo espongo all'utente, quindi funziona bene per me. Permette a me di ottenere o la chiave come ho bisogno di.
Il KeyPair<,>
è necessario per poter implementare il IEnumerable<,>
e quindi il metodo Add
in modo da poter utilizzare l'inizializzatore dell'oggetto.
internal class KeyPair<TKey1, TKey2>
{
public TKey1 Key1 { get; set; }
public TKey2 Key2 { get; set; }
}
Questa è la classe principale, come un oggetto dinamico in modo che possiamo usare nomi chiave su di esso durante il recupero di valori:
internal class BiDictionary<TKey1, TKey2> : DynamicObject, IEnumerable<KeyPair<TKey1, TKey2>>
{
private readonly Dictionary<TKey1, TKey2> _K1K2 = new Dictionary<TKey1, TKey2>();
private readonly Dictionary<TKey2, TKey1> _K2K1 = new Dictionary<TKey2, TKey1>();
private readonly string _key1Name;
private readonly string _key2Name;
public BiDictionary(string key1Name, string key2Name)
{
_key1Name = key1Name;
_key2Name = key2Name;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (binder.Name == _key1Name)
{
result = _K1K2;
return true;
}
if (binder.Name == _key2Name)
{
result = _K2K1;
return true;
}
result = null;
return false;
}
public void Add(TKey1 key1, TKey2 key2)
{
_K1K2.Add(key1, key2);
_K2K1.Add(key2, key1);
}
public IEnumerator<KeyPair<TKey1, TKey2>> GetEnumerator()
{
return _K1K2.Zip(_K2K1, (d1, d2) => new KeyPair<TKey1, TKey2>
{
Key1 = d1.Key,
Key2 = d2.Key
}).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Esempio:
dynamic bidic = new BiDictionary<string, string>("Key1", "Key2")
{
{ "foo", "bar" },
{ "baz", "qux" }
};
var bar = bidic.Key1["foo"];
var foo = bidic.Key2["bar"];
Essi possono andare fuori sincrono se si modifica uno qualsiasi dei dizionari esterni. A tale scopo, utilizzo ObservableDictionary
in modo da poter aggiornare l'altro se si cambia ma, per semplicità, ho rimosso questa parte del codice per dimostrare la logica principale.
Imposta la parte del valore della chiave. –
Non esiste una classe di questo tipo in .NET Framework. Ma puoi facilmente costruirne uno su un dizionario e su un hash o due dizionari. – dtb
@Robert Harvey: se lo fa non può più fare 'd [1]', cosa che sconfigge lo scopo del Dizionario. Potresti anche utilizzare HashSet <> –