The runtime indeed uses Equals to compare values. I didn't know about DateTimeOffset.EqualsExact and after reading the documentation I see it's ambiguous: Equals will tell you if the DateTimeOffset values represent the same point in time, but EqualsExact will tell you if those are also in the same timezone (as with multiple timezones you can have the same point in time but in different timezones), am I correct? (if not, I have no idea what it is for, sorry
)
So as this is ambiguous, the check whether values are equal therefore is ambiguous in this case and whatever we pick will have a downside.
The issue is that the check happens inside EntityCore<T>.SetValue(int fieldIndex, object value, bool performDesyncForFKFields, bool checkForRefetch)
, line 3105, where we call FieldUtilities.DetermineIfFieldShouldBeSet... which is a static method and which does a comparison based on Equals. There's no interception point to override the behavior there, so that makes it problematic to add the behavior you want.
Does the current behavior leads to fields being flagged as dirty while they shouldn't be flagged as dirty? I think with a bit of a workaround you could get that behavior but it's cumbersome: Override both OnSetValue() and OnSetValueComplete() in a partial class of CommonEntityBase, where you add code to check if the field is of type DateTimeOffset, and do the exact comparison in OnSetValue, and remember the value, then when OnSetValueComplete comes along, you check if the field is indeed marked dirty, and if so (and it shouldn't be marked dirty), correct the field's value in OnSetValueComplete... But admitted, it's ... not ideal