Home > Software engineering >  HashSet.SetEquals on two identical collections returns false
HashSet.SetEquals on two identical collections returns false

Time:05-26

I have two HashSet<T> collections containing the same items (that is, different instances of the objects but with the same values). From my understanding of the SetEquals method the following code should return true because the collection item property values are equal, but it returns false:

var source = new HashSet<AllocatedComponent>()
        {new AllocatedComponent() {
            Weighting = 100,
            ComponentId = 1, 
            Title = "Foo"}};
    
var destination = new HashSet<AllocatedComponent>()
        {new AllocatedComponent() {
            Weighting = 100,
            ComponentId = 1, 
            Title = "Foo"}};
    
Console.WriteLine(source.SetEquals(destination)); // False

Can anyone please explain what I'm doing wrong here? My goal is to check that the two collections contain the same number of items, and with the same property values.

I don't quite understand the Remarks section of the Microsoft documentation so may be overlooking something quite obvious.

Net Fiddle here

CodePudding user response:

As from the first comment to let the framework to compare the object using their data you have to override the 2 methods bool Equals(object o) and int GetHashCode(). The code below gives the desired result (please note that you have to use all the data members for both the implementations)

using System;
using System.Collections.Generic;

public class AllocatedComponent
 
{
    public double Weighting { get; set; }
    public int ComponentId { get; set; }
    public string Title { get; set; }
    
    public override bool Equals(object o)
    {
        if(!(o is AllocatedComponent))
           return false;
        AllocatedComponent ac = (AllocatedComponent)o;
        return ac.Title == this.Title && ac.ComponentId == this.ComponentId && ac.Weighting == this.Weighting;
    }   
    public override int GetHashCode()
    {
        return this.Title.GetHashCode();
    }
}

public class Program
{
    public static void Main()
    {
        var source = new HashSet<AllocatedComponent>()
            {new AllocatedComponent() {
                Weighting = 100,
                ComponentId = 1, 
                Title = "Foo"}};
        
        var destination = new HashSet<AllocatedComponent>()
            {new AllocatedComponent() {
                Weighting = 100,
                ComponentId = 1, 
                Title = "Foo"}};
        
        Console.WriteLine(source.SetEquals(destination)); // False
    }
}
  • Related