104 lines
4 KiB
Markdown
104 lines
4 KiB
Markdown
|
|
||
|
# C# Language Design Meeting for June 22, 2020
|
||
|
|
||
|
## Agenda
|
||
|
|
||
|
1. Data properties
|
||
|
|
||
|
1. Clarifying what's supported in records for C# 9
|
||
|
|
||
|
- Structs
|
||
|
|
||
|
- Inheritance with records and classes
|
||
|
|
||
|
## Discussion
|
||
|
|
||
|
### `data` properties
|
||
|
|
||
|
We've been working on an implementation for data properties and have some questions about
|
||
|
modifiers, which are currently not allowed.
|
||
|
|
||
|
There are some modifiers that could be legal, like `new`, `abstract`, `virtual`, and `override`.
|
||
|
Some of these, especially `new` and `override` would probably prevent `data` properties from
|
||
|
being used at all, since a warning would be generated if there's a matching member in the base
|
||
|
that requires either `override` or `new`.
|
||
|
|
||
|
However, the point of data properties was to be brief. Adding modifiers would potentially cloud
|
||
|
the purpose of the feature. The syntactical abbreviation isn't strictly required because the
|
||
|
equivalent property can always be written explicitly:
|
||
|
|
||
|
```C#
|
||
|
data int X;
|
||
|
|
||
|
// versus
|
||
|
|
||
|
public int X { get; init; }
|
||
|
```
|
||
|
|
||
|
|
||
|
**Conclusion**
|
||
|
|
||
|
Based on where we are in the schedule for C# 9, we probably will not have time to respond to feedback.
|
||
|
Therefore, we're planning on putting this feature into preview and not shipping it with C# 9. For now,
|
||
|
let's allow the following modifiers: `public`, `new`, `abstract`, `virtual`, and `override`. This will
|
||
|
provide an option for allowing `data` properties to interact more smoothly with other constructs in C#,
|
||
|
while maintaining some of the simplicity. We'll see how it feels in prototypes to gauge whether we went
|
||
|
too far, or not far enough.
|
||
|
|
||
|
### Struct records
|
||
|
|
||
|
We're not sure how much space we have for structs in C# 9, but we do think structs are an
|
||
|
interesting design point. We previously proposed that structs could support a variety of record
|
||
|
behaviors without being a record. One idea would be to automatically implement `IEquatable<T>`
|
||
|
for all structs, but this has a lot of potential negative impact for the runtime and the
|
||
|
ecosystem: effectively every struct would add a large number of members which could seriously
|
||
|
bloat metadata.
|
||
|
|
||
|
An alternative would be to work with the runtime to try to provide a runtime-generated form of
|
||
|
`IEquatable<T>`. If it's cheap enough, we may be able to provide `IEquatable<T>` for structs as
|
||
|
a as-necessary addition to all structs. However, this is a potentially very large change. Even
|
||
|
small costs could add up, and even small semantic changes could impact someone.
|
||
|
|
||
|
Overall, the modification of arbitrary struct semantics just seems too risky. Something as simple
|
||
|
as testing a struct for an implementation of `IEquatable<T>` could be a breaking change, and with
|
||
|
a change this big, it's almost certain to be breaking for someone.
|
||
|
|
||
|
**Conclusion**
|
||
|
|
||
|
Altering the semantics of all structs as-is is out. We're leaning towards a real "record struct"
|
||
|
declaration.
|
||
|
|
||
|
### Inheritance between records and classes
|
||
|
|
||
|
We currently have a restriction that records cannot inherit from classes and classes cannot
|
||
|
inherit from records. We should confirm that this restriction is acceptable for C# 9.
|
||
|
|
||
|
**Conclusion**
|
||
|
|
||
|
We definitely see scenarios for expanding this, but we think the restriction is fine for the
|
||
|
first version of records. Based on feedback and example scenarios, we can reconsider these
|
||
|
restrictions and also the expected semantics.
|
||
|
|
||
|
### `with` expressions on non-records
|
||
|
|
||
|
This encompasses:
|
||
|
|
||
|
1. Finding some way to define a compatible `Clone` for user-defined classes
|
||
|
|
||
|
1. Anonymous types
|
||
|
|
||
|
1. Tuples
|
||
|
|
||
|
Compatibility for `Clone` in user-defined classes is the most difficult of these items because it
|
||
|
relies on a new language feature for requiring that a new object is returned from the Clone
|
||
|
method.
|
||
|
|
||
|
Anonymous types are very simple, we can retroactively define them as record types.
|
||
|
|
||
|
Tuples would be simple to special-case in the language, but it's probably more consistent to
|
||
|
decide the semantics for struct records first, and then update the definition of
|
||
|
System.ValueTuple to support them.
|
||
|
|
||
|
**Conclusion**
|
||
|
|
||
|
Anonymous types can be updated at any time, everything else should wait until after C# 9.
|