# 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` 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`. If it's cheap enough, we may be able to provide `IEquatable` 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` 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.