3 Stimmen

Sollte das Aufrufen von indexOf Equals aufrufen?

Ich habe eine Liste < MyObj >

Ich habe auch Equals(Object) in der Klasse MyObj überschrieben.

Wenn ich indexOf in meiner Liste aufrufe, wird kein Index erhalten und equals wird nicht aufgerufen.

Ist meine Annahme richtig, dass Equals(Object) aufgerufen werden sollte, wenn ich indexOf aufrufe?

Wenn nicht, wie finde ich MyObj-Objekte, wenn ich keine genaue Referenz habe, aber die Objekte logisch gleich sind...?

hier ist der Code, den ich verwende

 public class TreeNode
    {
        private readonly List> _children = new List>();     

        public TreeNode(T value)
        {
            Value = value;
        }

        public virtual bool Equals(Object obj)
        {
            TreeNode treeNode = (TreeNode)obj;

            if (treeNode.Value.Equals(Value))
                return true;
            else
                return false;
        }

        public TreeNode this[int i]
        {
            get { return _children[i]; }
        }

        public TreeNode Parent { get; private set; }
        public T Value { get; set; }

        public ReadOnlyCollection> Children
        {
            get { return _children.AsReadOnly(); }
        }

        public TreeNode AddChild(T value)
        {
            var node = new TreeNode(value) { Parent = this };
            _children.Add(node);
            return node;
        }

        public bool RemoveChild(TreeNode node)
        {
            return _children.Remove(node);
        }

        public void Traverse(Action action)
        {
            action(Value);
            foreach (var child in _children)
                child.Traverse(action);
        }

    }

so rufe ich die Sammlung auf

  int artistIndex = serverDirs.Children.IndexOf(new TreeNode(artist));

Im Index, der zurückgegeben wird, ist immer -1, obwohl das Element in den Kindern vorhanden ist. Vielen Dank,

4voto

DocMax Punkte 11936

Die Informationen zu List.IndexOf auf MSDN beinhalten:

Diese Methode bestimmt die Gleichheit unter Verwendung des Standard-Gleichheitsvergleichers EqualityComparer.Default für T, den Typ der Werte in der Liste.

Und wenn Sie dem Link folgen, werden Sie feststellen, dass ja, es sei denn, Sie implementieren IEquatable für Ihre Klasse, der Standard-Vergleicher sowohl Ihre GetHashCode als auch Ihre Equals Methoden für MyObj verwendet. (Sie implementieren ja beide, oder?

1voto

Hans Passant Punkte 894572

Schauen Sie im Fehlerliste-Fenster nach dem Neuaufbau Ihres Programms:

Warnung CS0114: 'ConsoleApplication1.TreeNode.Equals(object)' versteckt geerbtes Element 'object.Equals(object)'. Um das aktuelle Element diese Implementierung überschreiben zu lassen, fügen Sie das Schlüsselwort "override" hinzu. Andernfalls fügen Sie das Schlüsselwort "new" hinzu. c:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll: (Zugehörige Datei)

Was Ihnen gesagt wird, ist, dass Ihre Equals() Methode tatsächlich nicht die Equals() Methode überschreibt, die der Gleichheitsvergleicher verwenden wird. Deshalb wird sie nicht aufgerufen und Sie erhalten eine -1-Rückgabe von IndexOf(). Behebung:

    public override bool Equals(Object obj) {        // HINWEIS: override, nicht virtual
        TreeNode treeNode = obj as TreeNode;
        if (treeNode == null) return false;
        return treeNode.Value.Equals(Value);
    }

Das löst Ihr Problem, auch wenn Sie jetzt eine neue Warnung erhalten:

Warnung CS0659: 'ConsoleApplication1.TreeNode' überschreibt Object.Equals(object o), überschreibt aber nicht Object.GetHashCode()

Ignorieren Sie das nicht, das wird früher oder später beißen. Behebung:

    public override int GetHashCode() {
        return Value.GetHashCode();
    }

Die Lehre aus diesem: ignorieren Sie keine Warnungen. Der Compiler hat oft recht, wenn er etwas Verdächtiges markiert. Und zögern Sie nicht, die IDE zu kritisieren, sie zeigt das Fehlerliste-Fenster nicht an, wenn es nur Warnungen gibt. Schlampig.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X