Introduction
In this article, we will see how to create a custom extension method to compare 2 lists in C#.
Custom Extension Method
Create a static class ExtensionDemo. Inside that, have a static method "CompareList" of generic type and return type of bool. Make sure to have 2 List parameters and the first one should have "this" keyword. This parameter here refers to the list in which you are able to see this custom extension method.
I have used the system.reflection.propertyinfo namespace to compare each property in an object. To know more about comparing properties inside 2 objects using Properties, please check this article.
public static class ExtensionDemo
{
public static bool CompareList<T>(this List<T> list1, List<T> list2)
{
// If any of the lists is null, return false
if ((list1 == null && list2 != null) || (list2 == null && list1 != null))
return false;
// If both lists are null, return true since they are the same
else if (list1 == null && list2 == null)
return true;
// If the counts don't match between the two lists, return false
if (list1.Count != list2.Count)
return false;
bool IsEqual = true;
foreach (T item in list1)
{
T Object1 = item;
T Object2 = list2.ElementAt(list1.IndexOf(item));
Type type = typeof(T);
// If any of the objects inside the list is null and the other list has some value for the same object, then return false
if ((Object1 == null && Object2 != null) || (Object2 == null && Object1 != null))
{
IsEqual = false;
break;
}
foreach (System.Reflection.PropertyInfo property in type.GetProperties())
{
if (property.Name != "ExtensionData")
{
string Object1Value = string.Empty;
string Object2Value = string.Empty;
if (type.GetProperty(property.Name).GetValue(Object1, null) != null)
Object1Value = type.GetProperty(property.Name).GetValue(Object1, null).ToString();
if (type.GetProperty(property.Name).GetValue(Object2, null) != null)
Object2Value = type.GetProperty(property.Name).GetValue(Object2, null).ToString();
// If any of the property values inside an object in the list didn't match, return false
if (Object1Value.Trim() != Object2Value.Trim())
{
IsEqual = false;
break;
}
}
}
}
// If all the properties are the same, then return true
return IsEqual;
}
}
How to use the created custom extension method.
To test this, we have to create a new Web/Window/Console project. I am using a web application. I have created a student class as shown below in the same namespace.
public class Student
{
public int? StudentId { get; set; }
public int Age { get; set; }
}
Now in page_load event, create a list of objects for students.
protected void Page_Load(object sender, EventArgs e)
{
List<Student> s1 = new List<Student>()
{
new Student() { studentId = 100, age = 21 },
new Student() { studentId = 101, age = 21 },
new Student() { studentId = 102, age = 21 }
};
List<Student> s2 = new List<Student>()
{
new Student() { studentId = 100, age = 21 },
new Student() { studentId = 101, age = 21 },
null
};
List<Student> s3 = new List<Student>()
{
new Student() { studentId = 100, age = 21 },
new Student() { studentId = 102, age = 21 },
new Student() { studentId = 102, age = 21 }
};
List<Student> s4 = new List<Student>()
{
new Student() { studentId = 100, age = 21 },
new Student() { studentId = 101, age = 21 },
new Student() { studentId = 102, age = 21 }
};
List<Student> s5 = new List<Student>()
{
new Student() { studentId = 100, age = 21 },
new Student() { studentId = 101, age = 21 },
new Student() { studentId = 102, age = 22 }
};
}
Now we are going to compare 2 lists using the extension method. You will be able to see the created custom extension in the list of extension methods for list s1 as below.

Now I compared a few combinations to verify that the method is working in the page_load event.
// Compare two lists with different counts
bool same = s1.CompareList(s2);
// Compare two lists with the same number of objects but one of the properties inside an object is different (Student ID property)
bool same1 = s1.CompareList(s3);
// Compare two lists with the same count and values
bool same2 = s1.CompareList(s4);
// Compare two lists with the same number of objects but one of the properties inside an object is different (Age property)
bool same3 = s1.CompareList(s5);
// Compare two lists in which one of the lists is null
List<Student> s6 = null;
bool same4 = s1.CompareList(s6);
// Compare two lists, both of which are null
List<Student> s7 = null;
bool same5 = s6.CompareList(s7);
// Reinitialize s1
s1 = new List<Student>()
{
new Student() { studentId = 100, age = 21 },
new Student() { studentId = 101, age = 21 },
null
};
// Compare two lists in which one of the objects inside a list is null
bool same6 = s1.CompareList(s4);
While debugging, same2 and same5 will return true, all the remaining items will return false.
Please find the attached complete source code.

SubashPosted Aug 30, 2016, 12:48 PM
Great
james.curranPosted May 25, 2012, 12:27 PM
Hmmmm.... Let's see what we can do to improve this. First of all, your "compare two object via reflection" routine is nice, except it should be stuck in the middle of a list comparing method. It should be a method by itself. Well, actually, maybe not, because it's broken. It should work fine if all your properties return native types (or classes which define ToString()) Try this: Add a new property to Student: public Student BestFriend { get; set; } Since Student doesn't define a ToString method, it inherits Object's ToString() which just returns the full class name. Hence for the BestFriend property for every Student object, you'll just be comparing the string "CustomExtensionMethodToCompareList.Student" to itself. The best way to handle that it just to push the job off onto the objects themselves: public static bool CompareList<T>(this List<T> list1, List<T> list2) where T:IEqualable<T> ... isEqual = Object1.Equals(Object2); if (!isEqual) break; Move upwards: I'm all in favor of using foreach when appropriate, but here for() is what's needed: for(int inx =0; inx <list1.Count, ++inx) { T Object1 = list1[inx]; T Object2 = list2[inx]; And, reaching the top, your initial if() treat each question as an indivisible unit, taking no knowledge of what came before. Those 6 if()s can be reduced to 3: if (list1 == null) return (list2 == null); // list 1 must be !null if (list2 == null) return false