# 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.