Add meeting notes for Feb. 19, 2020
This commit is contained in:
parent
33a60a1db1
commit
82e330685f
82
meetings/2020/LDM-2020-02-19.md
Normal file
82
meetings/2020/LDM-2020-02-19.md
Normal file
|
@ -0,0 +1,82 @@
|
|||
|
||||
# C# Language Design for Feb. 19, 2020
|
||||
|
||||
## Agenda
|
||||
|
||||
Exploring Value Equality
|
||||
|
||||
## Discussion
|
||||
|
||||
Proposal: https://github.com/dotnet/csharplang/issues/3213
|
||||
|
||||
* We haven't decided (yet) to add support for value equality on all
|
||||
classes (separate from records)
|
||||
|
||||
* The behavior is actually that all fields _declared_ in the class are
|
||||
members in the value equality, not all fields in the class (since inherited fields are not
|
||||
included)
|
||||
|
||||
* Inheritance would be implemented using the previously described
|
||||
proposals using the `EqualityContract` property
|
||||
|
||||
* Records wouldn't behave differently, except that they have `value` by
|
||||
default
|
||||
|
||||
* The main difference with how records work in other places is that the semantics
|
||||
of a record is otherwise decided by the members of the primary constructor, while in this
|
||||
proposal the members of the record primary constructor have no special contribution to the value
|
||||
equality semantics
|
||||
|
||||
* There's an evolution risk where we want to provide more complex things, like deep
|
||||
equality, but these features don't support enough complexity to add it. Instead, we end up just
|
||||
adding more keywords or more attributes. Consider array fields. The default equality is reference
|
||||
equality, but sequence equality isn't particularly rare. How would users customize that?
|
||||
A new keyword? Attribute? Writing Equals manually?
|
||||
|
||||
* Turns out we're finding a lot of customization pivots. String comparison is another one.
|
||||
If we want to support all these scenarios attributes could be better. If we could use
|
||||
attributes to supply an EqualityComparer that would be almost completely customizable.
|
||||
|
||||
* If equality is this complicated, should we only support simple generated equality for
|
||||
records? Can we leave more complicated scenarios to tooling, like source generators?
|
||||
|
||||
Record equality: use the "primary" members or use all fields?
|
||||
|
||||
* Using all the fields is consistent with how structs work
|
||||
|
||||
* Using the "primary" members mirrors how the generation of `With` or other things
|
||||
generated by a record with a primary constructor
|
||||
|
||||
* There does seem to be a possibility that after you get to a certain size, positional
|
||||
records are less useful. In that case we want a path to the nominal record. If we do want the
|
||||
nominal path, it's generally desirable that we want as little "record" syntax as possible.
|
||||
If we choose the struct "use all the fields" approach, then we could use exactly the
|
||||
same mechanism for both the "nominal" and the "positional" records.
|
||||
|
||||
* The nominal record syntax that has been floated is
|
||||
|
||||
```C#
|
||||
record Point { int X; int Y; }
|
||||
```
|
||||
|
||||
which generates
|
||||
|
||||
```C#
|
||||
record Point
|
||||
{
|
||||
public int X { get; init; }
|
||||
public int Y { get; init; }
|
||||
}
|
||||
```
|
||||
|
||||
Aside from the shorthand for properties, this generates Equals, GetHashCode and some form
|
||||
of "With", which doesn't seem much different from proposals for a separable value equality. Is
|
||||
there really much point in separating these proposals?
|
||||
|
||||
* One completely opposite possibility: bypass the question by prohibiting private members in the
|
||||
positional record entirely
|
||||
|
||||
**Conclusion**
|
||||
|
||||
No hard decisions yet. Leaning slightly towards using "all declared fields" as the metric for
|
||||
value equality. There's some support for the "no private fields approach."
|
Loading…
Reference in a new issue