Skip to content

[Version 9.0] Feature support for record classes - #1458

Draft
BillWagner wants to merge 13 commits into
draft-v9from
v9-records
Draft

[Version 9.0] Feature support for record classes#1458
BillWagner wants to merge 13 commits into
draft-v9from
v9-records

Conversation

@BillWagner

@BillWagner BillWagner commented Nov 7, 2025

Copy link
Copy Markdown
Member

All commits from #983 have been squashed and added to this PR.

This PR / feature makes numerous changes to the grammar. We still need corresponding updates to the test and validation suite.

The following notes are carried over for additional work needed:

A. I put the new subclause "With expression" prior to "Arithmetic operators", which once the V8 features "Indices and Ranges" and "Pattern matching" have been merged, should immediately follow "Range operator" and "Switch expression." Make sure these are all in the correct place. 12.4.2 Operator precedence and associativity will also need to be revised accordingly.

B. New subclause §rec-class-prtmem Printing members mentions a method System.Runtime.CompilerServices.RuntimeHelpers.EnsureSufficientExecutionStack(). It's quite possible that this is an implementation-specific detail, in which case, we'll need to find words to make it abstract, and possibly update the Portability annex accordingly.

@BillWagner BillWagner changed the title Feature support for records [Version 9.0] Feature support for records Nov 7, 2025
@RexJaeschke RexJaeschke added this to the C# 9.0 milestone Nov 8, 2025
Comment thread standard/expressions.md Outdated
Comment thread standard/expressions.md

An awaiter’s implementation of the interface methods `INotifyCompletion.OnCompleted` and `ICriticalNotifyCompletion.UnsafeOnCompleted` should cause the delegate `r` to be invoked at most once. Otherwise, the behavior of the enclosing async function is undefined.

## §with-expressions With expressions

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add "with" as a new row to the table in the (earlier) section "Operator precedence and associativity." And as we have historically organized the sections in this clause in descending precedence order, we might need to move this new section up or down, accordingly.

Comment thread standard/classes.md Outdated
Comment thread standard/classes.md
Comment thread standard/classes.md Outdated
Comment thread standard/classes.md Outdated
Comment thread standard/classes.md Outdated
Comment thread standard/classes.md Outdated
Comment thread standard/classes.md Outdated
Comment thread standard/classes.md

The method performs the following tasks:

1. Calls the method `System.Runtime.CompilerServices.RuntimeHelpers.EnsureSufficientExecutionStack()` if that method is present and the record class has printable members.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to expose this type in the spec?

@RexJaeschke RexJaeschke added the Review: pending Proposal is available for review label Nov 8, 2025
Comment thread standard/classes.md Outdated
Comment thread standard/classes.md Outdated
Comment thread standard/classes.md Outdated
Comment thread standard/classes.md Outdated
Comment thread standard/classes.md Outdated
Comment thread standard/classes.md Outdated
Comment thread standard/classes.md Outdated
@RexJaeschke RexJaeschke added the type: feature This issue describes a new feature label Nov 11, 2025
@Nigel-Ecma Nigel-Ecma self-assigned this Nov 19, 2025
@Nigel-Ecma Nigel-Ecma removed their assignment Apr 26, 2026
@RexJaeschke RexJaeschke changed the title [Version 9.0] Feature support for records [Version 9.0] Feature support for record classes May 9, 2026
@RexJaeschke

Copy link
Copy Markdown
Contributor

Based on Issue #1683, I have updated the grammar for class_declaration.

Re my choice of grammar rule name prefixes, “non-record” and “record,” for a reader starting at 15.1, which says nothing about records, you might think we should not use the word “record” here. I’m OK with that. As a strawman, how about we call the two class flavors “plain class” and “record class?” (I think “class” and “record class” is not a clear enough distinction, as “class” might mean any class or just a non-record class.)

I currently use the two-favor distinction in new definitions, as follows:

A non_record_class_declaration declares a non-record class, while a record_class_declaration declares a record class.

This might then become:

A plain_class_declaration declares a plain class, while a record_class_declaration declares a record class.

I’m thinking that all existing uses of “class” will apply to both flavors, so no distinction will be needed for them.

For now, I’ll use “non-record” and “record.”

@BillWagner

Copy link
Copy Markdown
Member Author

An earlier version of this feature is already present on alpha-v9 from a prior meeting. Edits made to this PR since then are not yet on alpha-v9; they will land at the next propagation. If you need them on alpha-v9 sooner, please open a separate PR targeting alpha-v9.
Thanks!

@RexJaeschke

Copy link
Copy Markdown
Contributor

After researching and writing-up "Primary constructors" as a general feature in v12 for classes and structs outside of record variants, I have made a lot of tweaks to this spec (and to the V10 record struct spec) to ease the transition to that v12 spec.

@jskeet jskeet added the meeting: discuss This issue should be discussed at the next TC49-TG2 meeting label Jul 22, 2026
@jskeet

jskeet commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Applied "meeting: discuss" so that we can all perform a first round of review before the next meeting.

BillWagner added a commit that referenced this pull request Jul 24, 2026
…Rs; -X theirs for stale-feature conflicts)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
BillWagner added a commit that referenced this pull request Jul 24, 2026
…monize to 'provided' per refreshed #1458, keep Sealing paragraph
BillWagner added a commit that referenced this pull request Jul 24, 2026
Surgical wording-only propagation of the committee-approved #1458 records
refresh onto draft-v11's existing section structure (no heading/section
moves). Harmonizes #1550 to 'provided' while keeping the Sealing paragraph.
classes.md 'synthesized' prose reduced 40→~6 (kept: async entry-point,
positional/copy-constructor concepts, and the #1550 Sealing paragraph).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
BillWagner added a commit that referenced this pull request Jul 24, 2026
Surgical wording-only propagation onto v11-alpha's existing structure
(no heading/section moves). Harmonizes #1550 to 'provided', keeps the
Sealing paragraph. Matches refreshed draft-v11 records content.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
BillWagner added a commit that referenced this pull request Jul 24, 2026
Surgical wording-only propagation onto draft-v12's existing structure
(no heading/section moves). Harmonizes #1550 to 'provided', keeps the
Sealing paragraph. Completes the v9→v12 records refresh cascade.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

meeting: discuss This issue should be discussed at the next TC49-TG2 meeting Review: pending Proposal is available for review type: feature This issue describes a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants