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


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