MVC SelectListItem没有实现Equals吗

本文关键字:Equals 实现 SelectListItem MVC | 更新日期: 2023-09-27 18:22:14

忙于为控制器编写单元测试,该控制器生成一个视图模型,该模型包括IEnumerable<选择ListItem>。我尝试检查期望的列表是否包含视图模型中的所有列表,反之亦然。令我惊讶的是,这总是假的。所以我创建了以下测试:

[TestMethod]
public void CanEqual()
{
  var x = new SelectListItem {Selected = false, Text = "A", Value = "A"};
  var y = new SelectListItem { Selected = false, Text = "A", Value = "A" };
  Assert.AreEqual(x, y); 
}

断言总是失败,但两者是相等的。SelectListItem真的没有实现Equals吗?还是我只是缺少了一些东西?

MVC SelectListItem没有实现Equals吗

添加到Shark的答案中。。。至于该怎么办,除了在派生类上实现IEquatable<T>(如果你这样做,你真的应该重写非泛型Equals()——如果你这样,你真应该重写GetHashCode())。。。无论如何除此之外,您还可以:

  1. 在测试项目中创建一个辅助方法来进行值比较(可以使用Reflection编写一个适用于大多数简单类的通用方法),或者
  2. 为需要比较的每种类型创建一个实现IEqualityComparer<T>的助手类

两者都不允许您使用Assert.AreEqual(),但总的来说,我不赞成仅仅为了允许测试而将代码添加到对象中——更喜欢将其保留在测试项目中。此外,使用这些方法,您将不需要实现GetHashCode()

这是因为默认情况下,它正在测试相同的引用。在这种情况下,您有两个对象实例,因此它们不"相等"。

如果您想改变这种行为,只需要实现IEquatable<T>接口,就可以重新定义Equals()将返回的内容。例如:

public bool Equals(YourClass other)
{
    return (this.Value == other.Value);
}

有关Object.Equals()的良好参考资料,请参阅此MSDN参考资料。引用类型的相等性基于它们的引用。即,如果它们不引用相同的对象,则Equals()将返回false