
# 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.Type`s slow? Does it require reflection?

A: `typeof` does not require reflection and comparing `Type`s 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. 