Collections in records should be compared with value equality instead of reference equality #4845
Replies: 7 comments 12 replies
-
As a workaround you can implement a struct wrapper like ArrayEquatable which will wrap an array and compare elements one by one. I guess it is not ideal but if you value structured array equality then you need to make something like that a domain type. |
Beta Was this translation helpful? Give feedback.
-
Not every collection uses the same comparer. Arrays don't have a For arrays and collections that don't have Value based collection equality methods should exist, but in my opinion using |
Beta Was this translation helpful? Give feedback.
-
TBH I think the correct response here it what F# does: you get a compiler warning if you put non-equatable reference types inside a record. |
Beta Was this translation helpful? Give feedback.
-
Just taking a step back, I understand there are technical issues that would complicate implementing this feature. Functionally, if we say that record equality is determined by the values in the record, would you expect that the equality of all the properties in that record are value based. @Richiban suggestion about compiler warnings makes sure you don't break the value equality expectation. But that means you can't use a list (I mean the generic term not the c# class) of values in a record. That would be a shame, I can imagine use cases for implementing valueobjects (in a ddd context) that have a list of other values or valueobjects. Would this mean we need a new list structure for records, a recordlist that is immutable and has default value equality? |
Beta Was this translation helpful? Give feedback.
-
So then (two years later!) this is a documentation issue, because here... ...it doesn't say anything about a record's value equality not applying to collections inside the type. I've submitted documentation feedback, and @sanderobdeijn, I encourage you to as well. |
Beta Was this translation helpful? Give feedback.
-
I am in favour of deep equality for collections in records. Kotlin language also has records, called "data classes". In Kotlin, array equality is reference-based, whilst list equality is structurally-based. If you want a deep collection equality in your data classes, you can use lists instead of arrays. From Stack Overflow answer: // kotlin code
val list1 = listOf(1, 2, 3)
val list2 = listOf(1, 2, 3)
val array1 = arrayOf(1, 2, 3)
val array2 = arrayOf(1, 2, 3)
// side note: using a==b is the same as a.equals(b)
val areListsEqual = list1 == list2 // true
val areArraysEqual = array1 == array2 // false I understand that changing existing classes like List for deep equality could be troublesome, but maybe we could have a DeepEqualsList? |
Beta Was this translation helpful? Give feedback.
-
One of the properties of a record is value equality, but when you use a collection in a record you break this expectation.
For example: here I would expect result to be true but it is false.
Using collections in a record also has some issues with immutability but I expect this could be fixed by using collection from the System.Collections.Immutable namespace.
Beta Was this translation helpful? Give feedback.
All reactions