In this article I will explain how to get distinct list of custom objects using LINQ in VB.Net and C#
By default the LINQ Distinct function works only for simple data types and not for custom business class objects, in order to make it work we need add the IEquatable attribute, Equals and GetHashCode functions to the class as shown below.
C#
public class Person : IEquatable<Person>
{
    public string FirstName { get; set; }
   
    public string LastName { get; set; }
 
    public int Age { get; set; }
 
    public bool Equals(Person person)
    {
        return (this.FirstName.Equals(person.FirstName) && this.LastName.Equals(person.LastName));
    }
 
    public override int GetHashCode()
    {
        int hFirstName = this.FirstName != null ? this.FirstName.GetHashCode() : 0;
        int hLastName = this.LastName != null ? LastName.GetHashCode() : 0;
        return hFirstName ^ hLastName;
    }
}
 
VB.Net
Public Class Person
    Implements IEquatable(Of Person)
    Public Property FirstName As String
    Public Property LastName As String
    Public Property Age As Integer
  
    Public Function Equals1(ByVal person As Person) As Boolean Implements IEquatable(Of Person).Equals
        Return (Me.FirstName.Equals(person.FirstName) AndAlso Me.LastName.Equals(person.LastName))
    End Function
 
    Public Overrides Function GetHashCode() As Integer
        Dim hFirstName As Integer = If(Me.FirstName IsNot Nothing, Me.FirstName.GetHashCode(), 0)
        Dim hLastName As Integer = If(Me.LastName IsNot Nothing, LastName.GetHashCode(), 0)
        Return hFirstName Xor hLastName
    End Function
End Class
 
 
In the above class I have overridden the GetHashCode function so that now whenever I fire a LINQ distinct query it will compare the Person custom class object based on both FirstName and LastName i.e. if for two persons the FirstName and LastName are different it will consider them as distinct objects and vice versa. To test the working I have create a sample function below.
In the below function I have added four items to the Person list of which one item John Smith  has been added twice. Thus when I fire the distinct LINQ query on the custom class business object it returns only 3 records instead of 4.
C#
private void GetDistinctPersons()
{
    List<Person> persons = new List<Person>();
    persons.Add(new Person { FirstName = "John", LastName = "Smith", Age = 31 });
    persons.Add(new Person { FirstName = "John", LastName = "Doe", Age = 21 });
    persons.Add(new Person { FirstName = "John", LastName = "Smith", Age = 36 });
    persons.Add(new Person { FirstName = "Andrew", LastName = "Smith", Age = 25   });
    List<Person> distinctPersons = persons.Distinct().ToList() ;                            
}
 
VB.Net
Private Sub GetDistinctPersons()
    Dim persons As New List(Of Person)()
    persons.Add(New Person With {.FirstName = "John", .LastName = "Smith", .Age = 31})
    persons.Add(New Person With {.FirstName = "John", .LastName = "Doe", .Age = 21})
    persons.Add(New Person With {.FirstName = "John", .LastName = "Smith", .Age = 36})
    persons.Add(New Person With {.FirstName = "Andrew", .LastName = "Smith", .Age = 31})
    Dim distinctPersons As List(Of Person) = persons.Distinct().ToList()
End Sub
 
In the same way you can create your own custom equate functions to compare custom business objects and also find distinct LINQ queries.