进行以下课程和单元测试。
public class Entity
{
public object Id { get; set; }
public override bool Equals(object obj)
{
return this == (Entity)obj;
}
public static bool operator == (Entity base1, Entity base2)
{
if (base1.Id != base2.Id)
{
return false;
}
return true;
}
public static bool operator != (Entity base1, Entity base2)
{
return (!(base1.Id == base2.Id));
}
}
[TestMethod]
public void Test()
{
Entity e1 = new Entity { Id = 1 };
Entity e2 = new Entity { Id = 1 };
Assert.IsTrue(e1 == e2); //Always fails
}
有人可以解释为什么会失败吗?
答案 0 :(得分:8)
您的Id
媒体资源属于object
。当您使用1作为每个实例的Id构造两个实例时,您将最终得到两个不同的盒装对象。然后,您将使用 reference 相等来比较这些对象。
建议更改以解决此问题:
Id
的类型更改为int
类型。object.Equals
方法比较Ids而不是== 其中任何一个都可行,但第一个是优选的IMO。
如果您感兴趣,还有其他各种方法可以使实施更清洁,但我知道这可能只是一个虚拟的例子。快速列表一目了然:
GetHashCode
以及Equals
。Equals
覆盖不应无条件地执行转换,因为如果对象的类型错误,则会抛出异常。如果类型错误,则返回false。您当前的==实现可以简化为
return base1.Id == base2.Id;
!(base1 == base2)
来实施!=,除非您需要专家行为。Equals
可能会有问题。除非你计划继承,否则值得密封课程(国际海事组织 - 这可能会引起争议)。答案 1 :(得分:3)
因为您依赖比较器的对象引用:
public object Id { get; set; }
替换
public static bool operator == (Entity base1, Entity base2)
{
if (base1.Id != base2.Id)
{
return false;
}
return true;
}
使用
public static bool operator == (Entity base1, Entity base2)
{
return object.Equals(base1.Id, base2.Id);
}
答案 2 :(得分:2)
因为e1.Id和e2.Id是不同的对象。即使它们具有相同的值,它们也不是同一个对象,因此base1.Id == base2.Id失败。
答案 3 :(得分:2)
你的equals实现只是比较引用,而不是对象的内容。你实际上是在比较两个指针,因为你已经创建了两个独立的对象,你的相等就会失败。
有几篇关于如何正确实现Equals的文章,这是一个开始:
http://weblogs.asp.net/tgraham/archive/2004/03/23/94870.aspx
对于数据库实体,您可以通过比较数据库ID来执行快捷方式Equals实现,假设系统中两个具有相同ID的对象被视为“相等”。
答案 4 :(得分:2)
您的Id是一个对象,而不是一个int。对于对象,==运算符不会检查值是否相等。
答案 5 :(得分:1)
因为你的Id属性是一个对象。
1(作为int)被装入堆对象,但每个1被装入一个单独的实例。由于Id是一个对象,base1.Id!= base2.Id条件检查引用相等而不是 value 相等,这就是你想要的。将Id更改为int,或使用Equals()而不是!=应该修复它。
答案 6 :(得分:0)
如果您将Id
成员设为int
,则会有效。但正如CookieOfFortune所说,当你比较两个对象时,它会查看它们是否是完全相同的对象,而不是它们是否具有相同的值。
答案 7 :(得分:0)
将Id的类型更改为int或其他值类型。问题是你正在比较2个对象,我认为这是你重载==运算符来解决的问题