What is the algorithm used by the memberwise equality test in .NET structs? I would like to know this so that I can use it as the basis for my own algorithm.
I am trying to write a recursive memberwise equality test for arbitrary objects (in C#) for testing the logical equality of DTOs. This is considerably easier if the DTOs are structs (since ValueType.Equals does mostly the right thing) but that is not always appropriate. I would also like to override comparison of any IEnumerable objects (but not strings!) so that their contents are compared rather than their properties.
This has proven to be harder than I would expect. Any hints will be greatly appreciated. I’ll accept the answer that proves most useful or supplies a link to the most useful information.
Thanks.
This is the implementation of
ValueType.Equalsfrom the Shared Source Common Language Infrastructure (version 2.0).It’s interesting to note that this is pretty much exactly the code that is shown in Reflector. That suprised me because I thought that the SSCLI was just a reference implementation, not the final library. Then again, I suppose there is a limited number of ways to implement this relatively simple algorithm.
The parts that I wanted to understand more are the calls to
CanCompareBitsandFastEqualsCheck. These are both implemented as native methods but their code is also included in the SSCLI. As you can see from the implementations below, the CLI looks at the definition of the object’s class (via it’s method table) to see if it contains pointers to reference types and how the memory for the object is laid out. If there are no references and the object is contiguous, then the memory is compared directly using the C functionmemcmp.If I wasn’t quite so lazy, I might look into the implementation of
ContainsPointersandIsNotTightlyPacked. However, I’ve definitively find out what I wanted to know (and I am lazy) so that’s a job for another day.