Ich habe eine (enum: int) AccessOptions, die verwendet wird, um ein Dictionary zu füllen, um einfache Zugriffeigenschaften für eine indizierte Liste von Benutzerprinzipalnamen widerzuspiegeln.custom == für Dictionary-Erweiterung denkt, dass sie leer sind
Ich brauchte Unit-Tests zu unterstützen -
Assert.AreEqual
<Dictionary<string, AccessOptions>,
Dictionary<string, AccessOptions>)
... speziell die chaotisch ist, und ruft den Gleichheitsoperator Sprache generic, die wirklich nur Referenzwerte überprüft - was ich brauche ist, dass zwei verschiedene zu etablieren Referenzobjekte enthalten dieselben Schlüssel nach Wert, und dass die zugehörigen Werte dieser Schlüssel jeweils übereinstimmen.
Also habe ich meinen eigenen Gleichheitsoperator geschrieben und eine Klasse erstellt, die das Dictionary erweitert, um zu vermeiden, Wörterbuchobjekte in meinem Projekt zu vermasseln. Wenn diese Methode in Visual Studio 2016 im Kontext des Debuggens eines Assert.AreEqual-Aufrufs eines Komponententests ausgeführt wird, gehen einige Dinge seitwärts und ich markiere sie unten mithilfe von Kommentaren.
public class SecretAccessRuleSet : Dictionary<string, AccessOptions>
{
public SecretAccessRuleSet() {}
public SecretAccessRuleSet(int size) : base (size) {}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
return obj.GetType() == GetType() && Equals((SecretAccessRuleSet) obj);
}
public static bool operator == (SecretAccessRuleSet a, SecretAccessRuleSet b)
{
if (ReferenceEquals(a, b))
{
return true;
}
/* When the below statement executes in debug, I can watch
* execution flow from the equality test against (object)a,
* straight to "return false" -- but execution does not actually
* return, but appears to jump directly to the foreach statement
* two blocks down. It might be important, or just a bug.
*/
if (((object)a == null) || ((object)b == null))
{
return false;
}
if (a.Count != b.Count)
{
return false;
}
/* Then when we get here, the visualizer highlights a; I advance
* one line and it highlights "in", which I assume is wherein an
* enumerator is initialized; I advance again and we jump to the
* end of the method! Literally to the end curly brace.
*/
foreach (var entry in a)
{
AccessOptions bOpt;
if (!b.TryGetValue(entry.Key, out bOpt)
|| bOpt != entry.Value)
{
return false;
}
}
// If we get here, they're equal
return true;
}
public bool Equals(SecretAccessRuleSet other)
{
return this == other;
}
public static bool operator !=(SecretAccessRuleSet a, SecretAccessRuleSet b)
{
return !(a == b);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
Die Testergebnisse zeigen, dass die Assert.AreEqual (a, b) Aufruf falsch zurück, aber ich habe sehr geringen Glauben, dass der Inhalt entweder Sammlung ausgewertet wurde, und ich verstehe nicht, warum.
Ich werde wahrscheinlich all das entfernen und eine separate Möglichkeit schaffen, diese zu testen, ohne einen Operator zu überschreiben, aber - was ist hier schiefgelaufen?
(. Vielen Dank allen, für Ihre Zeit)
Update: das Zeug zu geben habe ich vergessen, sind beide Sammlungen der erwartete Typ, nicht null, und beide enthalten 2 Einträge - die gleichen 2 Einträge , tatsächlich; Ich habe erwartet, dass der Gleichheitsoperator im Test wahr ist.
Update 2: Ich trennte die Null-Checks; "(object) a == null" ergibt false und setzt fort, aber "(object) b == null" erscheint als wahr zu bewerten und sendet die Ausführung an "return false" - aber wiederum die gleichen zwei Probleme bei der Ausführung kommt eigentlich nicht zurück, versucht aber, ein erstes aufzuzählen ... und b ist nicht wirklich null. Gibt es Gründe, b wäre ein gültiges Objekt, aber die Cast-Operation in (Objekt) b könnte fehlschlagen?
Während des Debuggens können Sie die Maus über 'a' bewegen und den Inhalt sehen. Wenn es leer ist, ist das dein Problem. – nhouser9
Wie nhouser9 sagte, überprüfen Sie, ob sie leer sind. Wenn Sie sehen, wie Ihr (Objekt) a direkt zu "false" zurückkehrt, ist es möglich, dass es null ist und nicht iteriert. – Memfisto
Siehe Update - leider habe ich nicht angegeben. Beide Sammlungen haben den erwarteten Typ, nicht null und haben jeweils zwei Einträge. (Wie es passiert, sie übereinstimmen.) – Niali