csharplang/meetings/2020/LDM-2020-02-03.md
2020-02-07 19:19:46 -08:00

2.3 KiB

C# LDM for Feb. 3, 2020

Agenda

Value equality

Discussion

We split our discussion between two proposals, which end up being very similar.

'key' equality proposal

https://github.com/dotnet/csharplang/pull/3127

Q: Is comparing System.Types slow? Does it require reflection?

A: typeof does not require reflection and comparing Types is fast.

Q: Why use a KeyEquals method?

A: To signify that value equals is used and delegate to the base equality, when the base opts-in to value equality. By having a well-known signature in metadata, no special attributes are required for derived types to discover the pattern.

Q: Is KeyEquals necessary? Can we use EqualityContractOrigin to figure out that the type implements value equality?

A: Yes, that seems like it should work.

Discussion

There's some concern that modifying the public surface area of the type itself without any type of modifier is too much magic. If we have some sort of modifier that goes on the type, in addition to the "key" members, it would be clear that the type implements value equality from the type declaration, in addition to the member declarations.

This dovetails into records as a whole in that it would allow the feature sets to be separable. If a type could have value equality or be a record, the features could be combined to produce a value record, or the value equality could be left off to allow a record with reference equality. There's some disagreement on whether this is a positive or a negative. If you view a record as appropriately having value equality, this is a negative, or vice versa.

'value' equality proposal

https://github.com/dotnet/csharplang/issues/3137

The most visible difference here is that value is the name of the modifier, instead of key. This more accurately reflects the term "value equality", but it's unfortunate that we already have the term "value type" which has a completely different meaning in the language.

At the moment the proposal also doesn't include the "extra" members, like a strongly typed Equals, the ==/!= operators, and IEquatable interface implementation.

There's an open question as to whether this feature is preferred for a discriminated union scenario or not. We have two examples in Roslyn of discriminated unions, our symbol tree and our bound tree, and they have almost completely different equality contracts.