Friday, 17 January 2014

Use of Distinct with Custom Class objects in C#

Description:

    You can get distinct class objects from the list of objects by using Distinct method if the class is C# .NET build-in class like string and int. But when you use Distinct with list of user defined custom class object, you may not get perfect result, to achieve this you need to override Equals and GetHashCode methods.

Use of Distinct with List of Custom Class objects in C#

public class UserDetails : IEquatable<UserDetails>
{
    public string UserName { get; set; }
    public string City { get; set; }
    public string Country { get; set; }

    public bool Equals(UserDetails userDetail)
    {

        //Check whether the compared object is null.  
        if (Object.ReferenceEquals(userDetail, null)) return false;

        //Check whether the compared object references the same data.  
        if (Object.ReferenceEquals(this, userDetail)) return true;

        //Check whether the UserDetails' properties are equal.  
        return UserName.Equals(userDetail.UserName) && City.Equals(userDetail.City)
                && Country.Equals(userDetail.Country);
    }

    // If Equals() returns true for a pair of objects   
    // then GetHashCode() must return the same value for these objects.  

    public override int GetHashCode()
    {

        //Get hash code for the UserName field if it is not null.  
        int hashUserName = UserName == null ? 0 : UserName.GetHashCode();

        //Get hash code for the City field.  
        int hashCity = City.GetHashCode();

        //Get hash code for the Country field.  
        int hashCountry = Country.GetHashCode();

        //Calculate the hash code for the GPOPolicy.  
        return hashUserName ^ hashCity ^ hashCountry;
    }
}
Here, We have override Equals and GetHashCode methods in UserDetails class

static void Main(string[] args)
{
    List<UserDetails> users = new List<UserDetails>();
    UserDetails u1 = new UserDetails { UserName = "User1", City = "London", Country = "UK" };
    UserDetails u2 = new UserDetails { UserName = "User2", City = "SanFrn", Country = "USA" };
    UserDetails u3 = new UserDetails { UserName = "User1", City = "London", Country = "UK" };
    users.Add(u1);
    users.Add(u2);
    users.Add(u3);

    // Distinct returns only two user details
    users = users.Distinct().ToList();
}
Thanks,
Morgan
Software Developer

Advertisements
Advertisements

1 comment:

  1. The description should be amended to "to achieve this you need to override Equals and GetHashCode methods and add the IEquatable attribute."

    GetHashCode and Equals alone are not enough for the Distinct method to work. Your code will compile, but the value from Distinct will still contain duplicates.





    ReplyDelete