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