Quindi ecco uno che funzionerà esattamente per tre chiavi. È possibile seguire il modello elencato per crearne uno per 4, 5, 6, ecc. Sarebbe un sacco di codice, ma non un compito particolarmente difficile (solo noioso).
Si noti che poiché c'è un dizionario per ciascuna parte della chiave, si userà un bel po 'di memoria; questo è il prezzo che si paga per la flessibilità dell'accesso molto efficace da qualsiasi chiave.
public class MultiKeyDictionary<T1, T2, T3>
{
private Dictionary<T1, Tuple<T1, T2, T3>> firstLookup = new Dictionary<T1, Tuple<T1, T2, T3>>();
private Dictionary<T2, Tuple<T1, T2, T3>> secondLookup = new Dictionary<T2, Tuple<T1, T2, T3>>();
private Dictionary<T3, Tuple<T1, T2, T3>> thirdLookup = new Dictionary<T3, Tuple<T1, T2, T3>>();
public void Add(Tuple<T1, T2, T3> values)
{
if (!firstLookup.ContainsKey(values.Item1) &&
!secondLookup.ContainsKey(values.Item2) &&
!thirdLookup.ContainsKey(values.Item3))
{
firstLookup.Add(values.Item1, values);
secondLookup.Add(values.Item2, values);
thirdLookup.Add(values.Item3, values);
}
else
{
//throw an exeption or something.
}
}
public Tuple<T1, T2, T3> GetFirst(T1 key)
{
return firstLookup[key];
}
public Tuple<T1, T2, T3> GetSecond(T2 key)
{
return secondLookup[key];
}
public Tuple<T1, T2, T3> GetThird(T3 key)
{
return thirdLookup[key];
}
public void RemoveFirst(T1 key)
{
var values = GetFirst(key);
firstLookup.Remove(values.Item1);
secondLookup.Remove(values.Item2);
thirdLookup.Remove(values.Item3);
}
public void RemoveSecond(T2 key)
{
var values = GetSecond(key);
firstLookup.Remove(values.Item1);
secondLookup.Remove(values.Item2);
thirdLookup.Remove(values.Item3);
}
public void RemoveThird(T3 key)
{
var values = GetThird(key);
firstLookup.Remove(values.Item1);
secondLookup.Remove(values.Item2);
thirdLookup.Remove(values.Item3);
}
}
Di seguito è un approccio completamente diverso. Invece di compilare una ricerca per ogni chiave, memorizza tutti i valori in una singola raccolta ed esegue una ricerca lineare per trovare un elemento per una determinata chiave. Avrà O (n) Cerca/Rimuovi ora, ma O (1) Aggiungi. L'implementazione precedente ha O (1) aggiungi, rimuovi e cerca, ma occupa molto più memoria per farlo.
public class MultiKeyDictionary2<T1, T2, T3>
{
private HashSet<Tuple<T1, T2, T3>> lookup = new HashSet<Tuple<T1, T2, T3>>();
private HashSet<T1> firstKeys = new HashSet<T1>();
private HashSet<T2> secondKeys = new HashSet<T2>();
private HashSet<T3> thirdKeys = new HashSet<T3>();
public void Add(Tuple<T1, T2, T3> values)
{
if (lookup.Any(multiKey => object.Equals(multiKey.Item1, values.Item1) ||
object.Equals(multiKey.Item2, values.Item2) ||
object.Equals(multiKey.Item3, values.Item3)))
{
//throw an exception or something
}
else
{
lookup.Add(values);
}
}
public Tuple<T1, T2, T3> GetFirst(T1 key)
{
return lookup.FirstOrDefault(values => object.Equals(values.Item1, key));
}
public Tuple<T1, T2, T3> GetSecond(T2 key)
{
return lookup.FirstOrDefault(values => object.Equals(values.Item2, key));
}
public Tuple<T1, T2, T3> GetThird(T3 key)
{
return lookup.FirstOrDefault(values => object.Equals(values.Item3, key));
}
public void RemoveFirst(T1 key)
{
var values = GetFirst(key);
if (values != null)
lookup.Remove(values);
}
public void RemoveSecond(T2 key)
{
var values = GetSecond(key);
if (values != null)
lookup.Remove(values);
}
public void RemoveThird(T3 key)
{
var values = GetThird(key);
if (values != null)
lookup.Remove(values);
}
}
Quindi cosa 't3' contenere nel tuo caso ? Gli oggetti 'MyType' non sono unici, quindi ci sono tre touple di oggetti che corrispondono. – Servy
Diversi dizionari in cui si aggiunge lo stesso insieme di valori? –
Per quanto mi riguarda non posso fare un array param per i parametri di tipo – Jodrell