C# 如何比较 Equals() 方法中的两个对象列表

标签 c# list unit-testing object equals

我有两个具有相同元素和值的对象列表:

parameters = new List<Parameter>() { new Parameter() { parameterName="value", parameterType="string"} }

参数类如下所示:

 public class Parameter
    {
        public string parameterName;

        public string parameterType;
    }

我想通过单元测试将它与具有相同元素和值的相同对象列表进行比较。

我的方法类(我在方法对象之前创建,它存储了参数对象列表):

public class Method
{
   public List<Parameter> parameters { get; set;}

   public string modifier { get; set; }

   public string name { get; set; }

   public string type { get; set; }


   public override bool Equals(object obj)
        {
            return this.modifier == ((Method)obj).modifier && this.name == ((Method)obj).name && this.type == ((Method)obj).type
                && this.parameters == ((Method)obj).parameters; 
        }
}

我的问题出在 Equals 方法中,在 this.parameters == ... 点:

public override bool Equals(object obj)
        {
            return this.modifier == ((Method)obj).modifier && this.name == ((Method)obj).name && this.type == ((Method)obj).type
                && this.parameters == ((Method)obj).parameters; 
        }

顺便说一句,此方法中的所有其他标准都有效。与对象相比,修饰符、名称和类型返回正确的值。因为这些是基本的字符串值,并且比较更容易。当我想对对象列表执行相同操作时,情况会变得更加复杂。

如何在此 Equals() 方法中比较两个参数对象列表,我是否需要比较每个元素(例如比较 parameterName>列表中所有对象的参数类型)?

最佳答案

您需要重写 Parameter 类中的 Equals 以及重写​​ GetHashCode 以维护哈希值(否则您将得到不同的哈希值)对于具有相同值的 2 个对象)。

public class Parameter
{
    public string parameterName;

    public string parameterType;

    public override bool Equals(object obj)
    {
        return parameterName == ((Parameter) obj)?.parameterName &&
               parameterType == ((Parameter) obj)?.parameterType;
    }

    public override int GetHashCode()
    {
        unchecked
        {
            var hashCode = parameterName != null ? parameterName.GetHashCode() : 0;
            hashCode = (hashCode * 397) ^ (parameterType != null ? parameterType.GetHashCode() : 0);
            return hashCode;
        }
    }
}

然后在比较列表时使用SequenceEqual:

public class YourClass
{
    public List<Parameter> parameters { get; set; }

    public string modifier { get; set; }

    public string name { get; set; }

    public string type { get; set; }
    
    public override bool Equals(object obj)
    {
        return modifier == ((YourClass)obj)?.modifier && 
               name == ((YourClass)obj)?.name && 
               type == ((YourClass)obj)?.type && 
               ( parameters == null && ((YourClass)obj)?.parameters == null || 
                 parameters != null && ((YourClass)obj)?.parameters != null && parameters.SequenceEqual(((YourClass)obj).parameters));
    }
    
    public override int GetHashCode()
    {
        unchecked
        {
            var hashCode = parameters != null ? parameters.GetHashCode() : 0;
            hashCode = (hashCode * 397) ^ (modifier != null ? modifier.GetHashCode() : 0);
            hashCode = (hashCode * 397) ^ (name != null ? name.GetHashCode() : 0);
            hashCode = (hashCode * 397) ^ (type != null ? type.GetHashCode() : 0);
            return hashCode;
        }
    }
}

关于C# 如何比较 Equals() 方法中的两个对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59503354/

相关文章:

azure - 由 Azure DevOps 执行时 xUnit 测试失败

c# - 我什么时候应该使用 "Invariant Language (Invariant Country)"作为程序集的中性语言?

c# - 我可以从 C++ 或 C# 程序中提取 MSI 包的内容吗?

c# - 如何在 WCF 服务上使用 Windows 身份验证访问服务器端的用户名?

javascript - 使用 Javascript 获取列表项,我可以更改项目顺序吗?

比较两个字典列表中值的 Pythonic 方法

c# - 我应该如何检查工厂在单元测试中创建的对象图

c# - .Net 与 Cocoa 字符串格式

python - 如何在matplotlib中绘制平均线?

ruby-on-rails - Controller 测试使用 Rspec 显示页面,它给出错误 nil & 并渲染空页面