Reputation: 6623
I know questions with same title have been asked before, but this is my case:
I want to compare two lists of custom objects which do not override Equals
nor they implement IEqualityComparer
but I want to compare them against a static comparison method like:
public class Custom
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
public static bool Compare(Custom A, Custom B)
{
return A.Prop1 == B.Prop1 && A.Prop2 == B.Prop2;
}
Assuming that the lists have the elements in same order:
List<Custom> l1 = new List<Custom> {new Custom { Prop1 = "A", Prop2 = "B"}, new Custom { Prop1 = "A", Prop2 = "B" } };
List<Custom> l2 = new List<Custom> { new Custom { Prop1 = "A", Prop2 = "B" }, new Custom { Prop1 = "A", Prop2 = "b" } };
I am trying to avoid a for like this:
if(l1.Count != l2.Count)return;
for (int i = 0; i < l1.Count; i++)
{
if(!Compare(l1[i], l2[i]))return;
}
bool comparisonResult = true;
using linq, but I guess I am missing something:
bool comparisonResult = l1.Any(x => l2.Any(y => Compare(x, y)));
This is what have tried, but it keeps returning true
when lists are not the same.
Upvotes: 5
Views: 3344
Reputation: 1
Now a days, the easiest way to compare a list of custom classes is by using records instead of classes.
Records automatically provides an implementation of IEquatable<T>
, which means you don't have to change Equals
and GetHashCode
method each time you want to add a new field (or remove).
Example Implementation Using Records
Step 1: Define the record object
public record Custom
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
Step 2: Method to compare two instances
public bool AreListsEqual(List<Custom> list1, List<Custom> list2)
{
return list1.SequenceEqual(list2);
}
Step 3: If the order of object isn't important, sort them by some field before compare
public bool AreListsEqual(List<Custom> list1, List<Custom> list2)
{
var sortedList1 = list1.OrderBy(x => x.Prop1).ToList();
var sortedList2 = list2.OrderBy(x => x.Prop1).ToList();
return sortedList1 .SequenceEqual(sortedList2 );
}
Upvotes: 0
Reputation: 1659
If you must use LINQ and don't want to implement an IEqualityComparer
for Custom
...
Assuming the two lists are in the proper sequence, you can make use of Zip
to create a new list with each item side-by-side, kind of like a Tuple
. You can then call All on that new list to call your static Compare
method:
List<Custom> l1 = new List<Custom> {new Custom { Prop1 = "A", Prop2 = "B"}, new Custom { Prop1 = "A", Prop2 = "B" } };
List<Custom> l2 = new List<Custom> { new Custom { Prop1 = "A", Prop2 = "B" }, new Custom { Prop1 = "A", Prop2 = "b" } };
bool comparisonResult = l1.Zip(l2, (x, y) => new { x, y }).All(z => Compare(z.x, z.y));
Upvotes: 4
Reputation: 37271
You can use All
bool comparisonResult = l1.All(x => l2.Any(y => Compare(x, y)));
This will return true only if all the items in l1 match the inner condition - which is that they exist in the l2. This is an easier to read way that applying "not" twice.
This will not solve the case of duplicated items in lists so you can:
Upvotes: 2