简体   繁体   中英

C# How can I compare two lists of objects in the Equals()-Method

I have two Lists of objects with the same elements and values:

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

the Parameter class looks like this:

 public class Parameter
    {
        public string parameterName;

        public string parameterType;
    }

and I want to compare it with an identical List of objects with the same Elements and Values, via an unit-test.

my Method Class(I created before Method objects, which have stored a List of Parameter objects):

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; 
        }
}

my problem is in the Equals method, at the point of 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; 
        }

By the way, all other criteria in this method are working. Modifier, name and type are returning the right value compared to the object. Because of these are basic string values and the comparison is much easier. It gets more complicated when I want to do the same for the List of objects.

How can I compare two Lists of Parameter-objects in this Equals()-Method, do I need to compare the elements each(like comparing parameterName and parameterType of all objects in the list)?

You need to override Equals in your Parameter class as well as overriding GetHashCode in order to maintain hashes (otherwise you will get different hashes for 2 objects that have same values).

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;
        }
    }
}

And then use SequenceEqual when comparing Lists:

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;
        }
    }
}

Terminology: "Compare" and "Equal" are two different things, Compare means finding out an order (which one comes first), while Equals just tests yes/no equal or not (identity).

You have to define for yourself what equal means to you. Is {1;2;3} the same as {3;2,1;} ? Not only you have to define, what equal lists are, but also what equal parameters are.

For the Compare of list you could use

 parameters.SequenceEquals(((other)Method)).parameters);

if order is important to you.

To compare the Parameters itself, you have to override the Equals of the parameter, or provide a custom EqualityComparer that you can pass to SequenceEquals.

Which actually does nothing else than comparing one by one, and breaking on the first mismatch.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM