Skip to content

Commit c889d4b

Browse files
BillWagnerYoussef1313tdykstra
authored
Record types can seal ToString in C# 10. (#24957)
* Add information on sealed ToString Fixes #24077 Beginning in C# 10.0, records may declare a `ToString` method as `sealed`. This prevents derived records from creating an override. Effectively, that means the `ToString` output will not include the runtime type information. (All members and values are displayed, because derived records will still have a PrintMembers method generated.) * add note on ToString. * fix a build warning introduced This was introduced in an earlier PR * Update docs/csharp/language-reference/builtin-types/record.md Co-authored-by: Youssef Victor <[email protected]> * Apply suggestions from code review Co-authored-by: Tom Dykstra <[email protected]> Co-authored-by: Youssef Victor <[email protected]> Co-authored-by: Tom Dykstra <[email protected]>
1 parent f4489ec commit c889d4b

File tree

4 files changed

+10
-5
lines changed

4 files changed

+10
-5
lines changed

docs/csharp/language-reference/attributes/general.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ The string provided as the first argument to the attribute constructor will be d
4545

4646
In C# 10, you can use constant string interpolation and the `nameof` operator to ensure the names match:
4747

48-
:::code language="csharp" source="snippets/ObsoleteExample.cs" ID="Snippet2" :::
48+
:::code language="csharp" source="snippets/ObsoleteExample.cs" id="Snippet2" :::
4949

5050
## `AttributeUsage` attribute
5151

docs/csharp/language-reference/builtin-types/record.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Records - C# reference"
33
description: Learn about the record type in C#
4-
ms.date: 02/25/2021
4+
ms.date: 07/01/2021
55
f1_keywords:
66
- "record_CSharpKeyword"
77
helpviewer_keywords:
@@ -136,7 +136,7 @@ The `ToString` override creates a <xref:System.Text.StringBuilder> object with t
136136

137137
:::code language="csharp" source="snippets/shared/RecordType.cs" id="ToStringOverrideDefault":::
138138

139-
You can provide your own implementation of `PrintMembers` or the `ToString` override. Examples are provided in the [`PrintMembers` formatting in derived records](#printmembers-formatting-in-derived-records) section later in this article.
139+
You can provide your own implementation of `PrintMembers` or the `ToString` override. Examples are provided in the [`PrintMembers` formatting in derived records](#printmembers-formatting-in-derived-records) section later in this article. In C# 10 and later, your implementation of `ToString` may include the `sealed` modifier, which prevents the compiler from synthesizing a `ToString` implementation for any derived records. Effectively, that means the `ToString` output will not include the runtime type information. (All members and values are displayed, because derived records will still have a PrintMembers method generated.)
140140

141141
## Inheritance
142142

@@ -185,6 +185,9 @@ Here is an example of code that replaces the synthesized `PrintMembers` methods,
185185

186186
:::code language="csharp" source="snippets/shared/RecordType.cs" id="PrintMembersImplementation":::
187187

188+
> [!NOTE]
189+
> In C# 10.0 and later, the compiler will synthesize `PrintMembers` when a base record has sealed the `ToString` method. You can also create your own implementation of `PrintMembers`.
190+
188191
### Deconstructor behavior in derived records
189192

190193
The `Deconstruct` method of a derived record returns the values of all positional properties of the compile-time type. If the variable type is a base record, only the base record properties are deconstructed unless the object is cast to the derived type. The following example demonstrates calling a deconstructor on a derived record.

docs/csharp/whats-new/tutorials/records.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Use record types - C# tutorial
33
description: Learn about how to use record types, build hierarchies of records, and when to choose records over classes.
4-
ms.date: 11/12/2020
4+
ms.date: 07/01/2021
55
---
66
# Create record types
77

@@ -125,6 +125,8 @@ You declare a `PrintMembers` method in the `DegreeDays` record that doesn't prin
125125

126126
The signature declares a `virtual protected` method to match the compiler's version. Don't worry if you get the accessors wrong; the language enforces the correct signature. If you forget the correct modifiers for any synthesized method, the compiler issues warnings or errors that help you get the right signature.
127127

128+
In C# 10.0 and later, you can declare the `ToString` method as `sealed` in a record type. That prevents derived records from providing a new implementation. Derived records will still contain the `PrintMembers` override. You would do this if you didn't want the `ToString` method to display the runtime type of the record. In the preceding example, you'd lose the information on where the record was measuring heating or cooling degree days.
129+
128130
## Non-destructive mutation
129131

130132
The synthesized members in a positional record don't modify the state of the record. The goal is that you can more easily create immutable records. Look again at the preceding declarations for `HeatingDegreeDays` and `CoolingDegreeDays`. The members added perform computations on the values for the record, but don't mutate state. Positional records make it easier for you to create immutable reference types.

docs/csharp/whats-new/tutorials/snippets/record-types/record-types.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net5.0</TargetFramework>
5+
<TargetFramework>net6.0</TargetFramework>
66
<RootNamespace>record_types</RootNamespace>
77
</PropertyGroup>
88

0 commit comments

Comments
 (0)