我有一个List< 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的索引中的,即使子项中存在该项 谢谢,
答案 0 :(得分:3)
MSDN上List<T>.IndexOf
的备注包括:
此方法使用T的默认相等比较器EqualityComparer.Default确定相等性,T是列表中值的类型。
如果您关注该链接,您会发现是的,除非您为您的班级实施IEquatable<T>
,否则默认比较器会同时使用您的GetHashCode
和Equals
方法{ {1}}。 (你 实现两者,对吗?
答案 1 :(得分: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(对象o),但不覆盖Object.GetHashCode()
不要忽略它,它迟早会变成字节。修正:
public override int GetHashCode() {
return Value.GetHashCode();
}
从中吸取教训:不要忽视警告。当标记出一些臭的东西时,编译器通常是正确的。并且随意责怪IDE,当只有警告时它不会显示错误列表窗口。马虎。