ValeraT1982 / ObjectsComparer

C# Framework provides mechanism to compare complex objects, allows to override comparison rules for specific properties and types.
MIT License
352 stars 86 forks source link

Disable usage of IComparable<T> #57

Open Velociraptor45 opened 11 months ago

Velociraptor45 commented 11 months ago

Hey, is it somehow possible to disable the usage of IComparable<T> and compare both objects as if they wouldn't implement that interface (without having to write custom comparison rules)?

Why would I want that? I use ObjectsComparer in my unit tests, where I compare two objects that should have the same content. But in my production code, I want to compare two objects based on one certain property in order to rank them in a SortedSet (which uses IComparable<T> to do so).

However, there seems to be a bug in it anyway, minimal example (should return true, but returns false - if you remove the interface, it's correct): https://dotnetfiddle.net/51zYFs

Is there a certain reason why you chose IComparable<T> and not IEqualityComparer<T>?

ValeraT1982 commented 11 months ago

"Hey, is it somehow possible to disable the usage of IComparable and compare both objects as if they wouldn't implement that interface (without having to write custom comparison rules)?" No. Unfortunately you cannot disable it.

"However, there seems to be a bug in it anyway, minimal example (should return true, but returns false - if you remove the interface, it's correct): https://dotnetfiddle.net/51zYFs" Yes. I think it's a bug. I'll fix it in the next version.

"Is there a certain reason why you chose IComparable and not IEqualityComparer?" Honestly I don't remember. :)

Velociraptor45 commented 11 months ago

I'm asking because when I read the documentation, the IComparable\ is used for sorting & ordering

Defines a generalized comparison method that a value type or class implements to create a type-specific comparison method for ordering or sorting its instances.

whereas, IEqualityComparer\ is used for checking for equality.

Defines methods to support the comparison of objects for equality.

I feel like determining equality by using this interface is a bug in general and should be fixed. As a user, I would not expect the library to use IComparable<T> to check for equality, as this is not what the interface is designed for.

ValeraT1982 commented 11 months ago

I see it as IEqualityComparer may also need to be checked and used to check equality if interface is implemented. Don't see a problem with checking for IComparable because it's also a "comparison method".

Velociraptor45 commented 11 months ago

yes, it's a comparison method but what your package does, is comparing the equality of objects (and even having the cool posibilty of giving you the diff between them). But when you do that, you can't use the IComparable<T> interface as it's not intended for equality comparison. Two sports clubs that both have 20 points in the league will be ranked at the same table place (IComparable<T> will return true, because their point total is the same and thus should have the same place in the table) but they are clearly not the same team (IEqualityComparer<T> will return false). And I don't see how ranking objects is intended by your package as you can only rank them if you know what to use for ranking (which is defined by IComparable<T> and if a class does not implement that, it should and can not be ranked without further knowledge). And if all rankable classes implement that interface, you don't need another package to tell you the ranking - that's what a SortedSet can do. On the other hand, equality is a whole different point. If I want to know if two objects contain the same values, I'd have to implement IEqualityComparer<T> for every of them, which is tedious and error prone. Plus, I maybe don't want to have that kind of equality comparison in my production code (see ValueObjects vs Entities in DDD). And that's when your package comes in handy. And if you don't want to drop the IComparable<T> support at all, maybe just give us the option to turn it off 😅