primo collegamento sul Trues veloci e falses:
if(ReferenceEqual(actual, expected))
return true;
if(actual == null || expected == null || actual.Count != expected.Count)
return false;
Questo gestisce anche nullo-checking quindi tutto il resto abbiamo non può lanciare un'eccezione di riferimento null. Puoi saltare tutta questa barra confrontando i conteggi se li hai appena dopo la creazione come nel tuo esempio, ma dovresti tenerlo dentro se lo metti in un metodo separato, per ogni evenienza.
Non possiamo semplicemente chiamare SequenceEqual sui due dizionari, perché non è garantito il recupero delle chiavi nello stesso ordine. Con altri tipi per il valore che si potrebbe fare:
return actual.OrderBy(kvp => kvp.Key).SequenceEqual(expected.OrderBy(kvp => kvp.Key));
Ma questo non funzionerà perché i due List<string>
valori della sequenza-parità non sarà considerato uguale al metodo DefaultEqualityComparer<List<string>>.Equals()
che ciò mettere in.
potremmo creare un IEqualityComparer<KeyValuePair<string, List<string>>>
se fossimo inferno-vincolati sull'uso SequenceEqual, ma è probabilmente più semplice per fare l'approccio non-Linq, anche se Linq è normalmente più semplice e concisa (una volta trovato il modo di farlo. Quindi:..
List<string> expectedVal;
foreach(KeyValuePair<string, List<string> kvp in actual)
{
if(!expected.TryGetValue(kvp.key, out expectedVal) || kvp.Value.Count != expectedVal.Count || !kvp.Value.SequenceEquals(expectedVal))
return false;
}
return true;
varianti possono trattare con diversi punti di vista di uguaglianza, ad esempio, possiamo utilizzare kvp.Value.OrderBy(x => x).SequenceEquals(expectedVal.OrderBy(x => x))
se volessimo considerare due liste degli stessi articoli in diversi ordini come uguale
in sintesi, il lotto:
if(ReferenceEqual(actual, expected))
return true;
if(actual == null || expected == null || actual.Count != expected.Count)
return false;
List<string> expectedVal;
foreach(KeyValuePair<string, List<string> kvp in actual)
{
if(!expected.TryGetValue(kvp.key, out expectedVal) || kvp.Value.Count != expectedVal.Count || !kvp.Value.SequenceEquals(expectedVal))
return false;
}
return true;
Edit: Solo per divertimento, il modo in cui utilizza SequenceEquals:
internal class KvpSLSEq : IEqualityComparer<KeyValuePair<string, List<string>>>
{
public bool Equals(KeyValuePair<string, List<string>> x, KeyValuePair<string, List<string>> y)
{
return x.Key == y.Key && x.Value.Count == y.Value.Count && x.Value.SequenceEquals(y.Value);
}
public int GetHashCode(KeyValuePair<string, List<string>> obj)
{
//you could just throw NotImplementedException unless you'll reuse this elsewhere.
int hash = obj.Key.GetHashCode;
foreach(string val in obj.Value)
hash = hash * 31 + (val == null ? 0 : val.GetHashCode());
}
}
Fatto questo possiamo usare la concisa:
actual.OrderBy(kvp => kvp.Key).SequenceEqual(expected.OrderBy(kvp => kvp.Key), new KvpSLSEq());
ma è veramente solo concisa se KvpSLSEq verrà utilizzato altrove anche.
Avete bisogno gli elementi in ciascuna lista per essere nello stesso ordine? – Rawling
Non penso che ci sia un metodo integrato. Date un'occhiata qui: http://stackoverflow.com/questions/3928822/comparing-2-dictionarystring-string-instances –
sì, tutto dovrebbe essere lo stesso, stessi valori, nello stesso ordine – user829174