I have attempted to create an extension method that looks like this...
public static IEnumerable<T> Distinct<T>(this IEnumerable<T> value, IEnumerable<T> compareTo, Func<T, object> compareFieldPredicate)
{
return value.Where(o => !compareTo.Exists(p => compareFieldPredicate.Invoke(p) == compareFieldPredicate.Invoke(o)));
}
The idea is that I would be able to do something like this...
IEnumerable<MyCollection> distinctValues = MyCollection.Distinct(MyOtherCollection, o => o.ID); //Note that o.ID is a guid
Now at this point I would have expected to have only my distinct items returned to me but what I found is that this was never the case.
Upon further research breaking down this method using the following code.
Guid guid1 = Guid.NewGuid();
Guid guid2 = new Guid(guid1.ToString());
Func<MyObject, object> myFunction = o => o.ID;
Func<MyObject, object> myFunction1 = o => o.ID;
bool result = myFunction(MyObject) == myFunction1(MyObject);
//result = false
I have found that infact even if the Guids are the same the comparison will always return false.
What is the cause of this?
Your problem is that you're boxing the Guids into Objects before you compare them. Consider this code:
Guid g1 = Guid.NewGuid();
var g2 = g1;
Console.WriteLine(g1 == g2);
object o1 = g1;
object o2 = g2;
Console.WriteLine(o1 == o2);
That actually outputs:
true
false
Since "o1" and "o2", while equal to the same Guid, are not the same object.
If you truly want your "Distinct" extension method to not be tied to a specific type (like Guid), you can do this:
public static IEnumerable<TItem> Distinct<TItem, TProp>(this IEnumerable<TItem> value, IEnumerable<TItem> compareTo, Func<TItem, TProp> compareFieldPredicate)
where TProp : IEquatable<TProp>
{
return value.Where(o => !compareTo.Any(p => compareFieldPredicate(p).Equals(compareFieldPredicate(o))));
}
bool result = (guid1==guid2); //result -> true
You can try to change return type Object to GUID in myfunction and myfunction1
Func<MyObject, Guid> myFunction = o => o.ID;
Func<MyObject, Guid> myFunction1 = o => o.ID;
Otherwise, the return value (true) is boxed to Object, and Reference equality is checked, which is false.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With