Es gab ein paar Antworten, die meiner Meinung nach ziemlich nahe dran waren, aber es gab ein paar zusätzliche Punkte, die meiner Meinung nach hinzugefügt werden sollten, also füge ich sie als weitere mögliche Antwort hinzu.
Erstens würde ich die Verwendung der Methode SequenceEquals vermeiden. Sie ist eine Erweiterungsmethode für Enumerable und setzt implizit voraus, dass die beiden Sammlungen in der gleichen Reihenfolge vorliegen. Dictionaries sind nicht dazu gedacht, geordnete Sammlungen zu sein, so dass die Verwendung von SequenceEquals bedeutet, dass Sie unnötigerweise über beide Dictionaries iterieren müssen, um sortierte/geordnete Zwischensammlungen zu erstellen, die Sie auch nicht benötigen, und dann über diese Sammlungen iterieren müssen, um sie auf Gleichheit zu vergleichen. Das scheint wirklich ineffizient und ein Missbrauch von LINQ zu sein, alles im Namen des Versuchs, sich kurz zu fassen und eine einzeilige Lösung zu schreiben. Wenn der OP's Idee von "elegant" ist kurz, ich denke, dies wird den Trick tun, aber es scheint verschwenderisch.
Andererseits, wenn die Vorstellung des Auftraggebers von "elegant" effizient ist, dann müssen Sie wahrscheinlich etwas mehr Code schreiben. Zunächst sollten Sie entweder die Equals-Methode für Ihre Klasse außer Kraft setzen oder IEquatable in Ihrer Klasse implementieren (siehe aquí zum Beispiel). So können Sie die Werte im Wörterbuch vergleichen. Dann werden Sie wahrscheinlich etwas tun wollen, wie eine Schnittstelle wie IEqualityComparer für Ihr Wörterbuch zu implementieren.
Dann würde der Vergleich der beiden Wörterbücher etwa wie folgt aussehen. Es ist nur ein schnelles und schmutziges "Back of the Napkin"-Beispiel, also kein Beispiel für den besten Weg, es zu tun, aber es soll einen Weg illustrieren, nur so oft wie nötig über das Wörterbuch zu iterieren und abzubrechen, sobald eine Ungleichheit gefunden wird.
Zunächst der erforderliche Code:
public class Foo
{
//members here...
public override bool Equals(object obj)
{
//implementation here
}
//You should probably also override GetHashCode to be thorough,
//but that's an implementation detail...
}
//This method could stand on its own or you could change it to make it
//part of the implementation of one of the comparison interfaces...
bool DictionariesEqual(Dictionary<K, V> x, Dictionary<K, V> y)
{
//If we're comparing the same object, it's obviously equal to itself.
if(x == y)
{
return true;
}
//Make sure that we don't have null objects because those are
//definitely not equal.
if (x == null || y == null)
{
return false;
}
//Stop processing if at any point the dictionaries aren't equal.
bool result = false;
//Make sure that the dictionaries have the same count.
result = x.Count == y.Count;
//If we passed that check, keep going.
if(result)
{
foreach(KeyValuePair<K, V> xKvp in x)
{
//If we don't have a key from one in the other, even though
//the counts are the same, the dictionaries aren't equal so
//we can fail out.
V yValue;
if(!y.TryGetValue(xKvp.Key, out yValue))
{
result = false;
break;
}
else
{
//Use the override of the Equals method for your object
//to see if the value from y is equal to the value from
//x.
result = xKvp.Value.Equals(yValue);
if(!result)
{
//If they're not equal we can just quit out.
break;
}
}
}
}
return result;
}
Dann würden wir es so verwenden:
Dictionary<string, Foo> dict1 = new Dictionary<string, Foo>();
Dictionary<string, Foo> dict2 = new Dictionary<string, Foo>();
//Fill the dictionaries here...
//Compare the dictionaries
bool areDictsEqual = DictionariesEqual(dict1, dict2);
Es ist also nicht der kürzeste Code, aber es wird auch nicht mehr als nötig iteriert. Meiner Meinung nach ist das eleganter.
Edit: Ein Kommentator schlug vor, die Codebeispiele zu aktualisieren, um sie allgemeiner zu machen. Ursprünglich habe ich mich an das Beispiel des ursprünglichen Posters gehalten, aber es schien mir eine gute Idee zu sein, es allgemeiner zu machen, mit einem Vorbehalt: Seien Sie vorsichtig, was der Typ des Schlüssels ist. Wenn es ein einfacher Typ wie ein String oder ein int ist, für den C# Gleichheitsimplementierungen enthält, sollte alles in Ordnung sein. Wenn der Schlüssel ein benutzerdefinierter Typ ist, müssen Sie sicherstellen, dass Sie die Funktion Equals()
y GetHashCode()
für Ihren benutzerdefinierten Typ.