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

brs*_*tkr 2 c# unit-testing list equals object

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

parameters = new List<Parameter>() { new Parameter() { parameterName="value", parameterType="string"} }
Run Code Online (Sandbox Code Playgroud)

参数类如下所示:

 public class Parameter
    {
        public string parameterName;

        public string parameterType;
    }
Run Code Online (Sandbox Code Playgroud)

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

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

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; 
        }
}
Run Code Online (Sandbox Code Playgroud)

我的问题出在 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; 
        }
Run Code Online (Sandbox Code Playgroud)

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

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

Rom*_*lko 5

您需要Equals在Parameter类中进行重写以及重写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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 旁注:在尝试将其强制转换之前检查类型...以及它们是否为“null”。 (2认同)
  • @Roman.Pavelko 如果您重写“Equals”,则还必须重写“GetHashCode”,以便“相等”对象返回相同的哈希码。 (2认同)