You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In C#, the default equality (Equals) for collections is reference equality, whereas other languages (C++, Java) provide value equality (they compare the elements by value).
In Ice 3.7 and before, we attempted to emulate this value equality in C# when mapping Slice structs to C# classes, with generated Equals and GetHashCode that perform "value equality". Unfortunately this implementation is not correct.
It uses Equals to compare the elements, which means each collection element won't be compared by value but by reference. So it's "by value" comparison is only one level deep. There are even more issues with the DictionaryEquals implementation that assumes the entries of the two IDictionaries being compared are in the same order.
I see two possible solutions:
a) don't attempt for perform deep value comparison in C# and just use the default reference equality for collections.
That's what ZeroC.Slice does already. It's the standard/expected behavior in C#. With this solution, we could reduce the generated code by mapping Slice to record classes in C#.
The downside is this change could break existing code that relies on this non-standard value equality semantics for mapped Slice structs.
b) implement value comparison correctly for collections. We'd need to check when an element is a collection (sequence or dictionary) and then recursively compare it by value. The proper way to do that in C# is by implementing an IEqualityComparer.
In C#, the default equality (Equals) for collections is reference equality, whereas other languages (C++, Java) provide value equality (they compare the elements by value).
In Ice 3.7 and before, we attempted to emulate this value equality in C# when mapping Slice structs to C# classes, with generated Equals and GetHashCode that perform "value equality". Unfortunately this implementation is not correct.
Take for example SequenceEquals:
ice/csharp/src/Ice/Collections.cs
Line 13 in 711bb29
It uses Equals to compare the elements, which means each collection element won't be compared by value but by reference. So it's "by value" comparison is only one level deep. There are even more issues with the DictionaryEquals implementation that assumes the entries of the two IDictionaries being compared are in the same order.
I see two possible solutions:
a) don't attempt for perform deep value comparison in C# and just use the default reference equality for collections.
That's what ZeroC.Slice does already. It's the standard/expected behavior in C#. With this solution, we could reduce the generated code by mapping Slice to record classes in C#.
The downside is this change could break existing code that relies on this non-standard value equality semantics for mapped Slice structs.
b) implement value comparison correctly for collections. We'd need to check when an element is a collection (sequence or dictionary) and then recursively compare it by value. The proper way to do that in C# is by implementing an IEqualityComparer.
See for example:
https://github.com/icerpc/icerpc-csharp/blob/5247e81134423a0114cb54a1da56a76ad7072c6b/src/IceRpc/Internal/DictionaryExtensions.cs#L5
See also #2126.
The text was updated successfully, but these errors were encountered: