3

私はリストを持っています<MyObj>

MyObjクラスのEquals(Object)もオーバーライドしました。

リストでindexofを呼び出すと、インデックスが取得されず、equalsは呼び出されません。

のインデックスを呼び出すときにEquals(Object)を呼び出す必要があるという私の仮定は正しいですか?

そうでない場合、正確な参照がなくてもオブジェクトが論理的に同じである場合、MyObjオブジェクトを見つけるにはどうすればよいですか、、、?

これが私が使っているコードです

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

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

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

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


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

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

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

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

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

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


    }

これが私がコレクションと呼んでいる方法です

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

アイテムが子供たちにあるにもかかわらず、常に-1で返されるインデックスでありがとう、

4

2 に答える 2

4

MSDNの備考List<T>.IndexOfは次のとおりです。

このメソッドは、リスト内の値のタイプであるTのデフォルトの等式比較子EqualityComparer.Defaultを使用して等式を判別します。

そして、そのリンクをたどると、そうですIEquatable<T>。クラスに実装しない限り、デフォルトの比較プログラムは、のメソッドGetHashCodeEqualsメソッドの両方を使用しますMyObj。(あなた両方を実装していますよね?

于 2012-10-27T05:47:55.490 に答える
1

プログラムを再構築した後、[エラーリスト]ウィンドウを確認します。

警告CS0114:'ConsoleApplication1.TreeNode.Equals(object)'は継承されたメンバー'object.Equals(object)'を非表示にします。現在のメンバーがその実装をオーバーライドするようにするには、overrideキーワードを追加します。それ以外の場合は、新しいキーワードを追加します。c:\ Windows \ Microsoft.NET \ Framework \ v2.0.50727 \ mscorlib.dll :(関連ファイル)

これが示しているのは、Equals()メソッドは、実際には、等式比較子が使用するEquals()メソッドをオーバーライドしないということです。これが、呼び出されていることが表示されない理由と、IndexOf()から-1が返される理由です。修理:

    public override bool Equals(Object obj) {        // NOTE: override, not virtual
        TreeNode<T> treeNode = obj as TreeNode<T>;
        if (treeNode == null) return false;
        return treeNode.Value.Equals(Value);
    }

これで問題は修正されますが、新しい警告が表示されます。

警告CS0659:'ConsoleApplication1.TreeNode'はObject.Equals(object o)をオーバーライドしますが、Object.GetHashCode()をオーバーライドしません

それを無視しないでください、遅かれ早かれバイトになります。修理:

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

これから学ぶべき教訓:警告を無視しないでください。コンパイラは、何か臭いものにフラグを立てるときに正しいことがよくあります。また、IDEのせいにしてください。警告しかない場合は、エラーリストウィンドウは表示されません。ずさんな。

于 2012-10-27T07:33:33.083 に答える