Skip to content

Commit 9b541c9

Browse files
committed
Finish conceptual docs
1 parent 662dae2 commit 9b541c9

File tree

13 files changed

+120
-17
lines changed

13 files changed

+120
-17
lines changed

docfx.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@
492492
"_csharplang/proposals/csharp-10.0/*.md": "08/07/2021",
493493
"_csharplang/proposals/csharp-11.0/*.md": "09/30/2022",
494494
"_csharplang/proposals/csharp-12.0/*.md": "08/15/2023",
495-
"_csharplang/proposals/*.md": "08/30/2024",
495+
"_csharplang/proposals/*.md": "10/31/2024",
496496
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "11/08/2022",
497497
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "09/26/2023",
498498
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "06/26/2024",
@@ -669,6 +669,7 @@
669669
"_csharplang/proposals/csharp-13.0/ref-struct-interfaces.md": "Allow ref struct types to implement some interfaces",
670670
"_csharplang/proposals/csharp-13.0/partial-properties.md": "All partial properties and indexers",
671671
"_csharplang/proposals/csharp-13.0/overload-resolution-priority.md": "Overload resolution priority tiebreaker attribute",
672+
"_csharplang/proposals/field-keyword.md": "The `field` contextual keyword",
672673
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "C# compiler breaking changes since C# 10",
673674
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "C# compiler breaking changes since C# 11",
674675
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "C# compiler breaking changes since C# 12",
@@ -791,6 +792,7 @@
791792
"_csharplang/proposals/csharp-13.0/ref-struct-interfaces.md": "This proposal provides features that enable interface authors to allow `ref struct` types to implement a particular interface",
792793
"_csharplang/proposals/csharp-13.0/partial-properties.md": "This proposal provides for partial properties and indexers, allowing the definition of a property or indexer to be split across multiple parts.",
793794
"_csharplang/proposals/csharp-13.0/overload-resolution-priority.md": "This proposal introduces a new attribute, `OverloadResolutionPriorityAttribute`, that can be applied to methods to influence overload resolution.",
795+
"_csharplang/proposals/field-keyword.md": "This proposal introduces a new keyword, `field`, that accesses the compiler generated backing field in a property accessor.",
794796
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "Learn about any breaking changes since the initial release of C# 10",
795797
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "Learn about any breaking changes since the initial release of C# 11",
796798
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "Learn about any breaking changes since the initial release of C# 12",
@@ -816,6 +818,7 @@
816818
"_csharplang/proposals/csharp-10.0/*.md": "C# feature specifications",
817819
"_csharplang/proposals/csharp-11.0/*.md": "C# feature specifications",
818820
"_csharplang/proposals/csharp-12.0/*.md": "C# feature specifications",
821+
"_csharplang/proposals/csharp-13.0/*.md": "C# feature specifications",
819822
"_csharplang/proposals/*.md": "C# feature specifications (preview)",
820823
"docs/framework/**/*.md": ".NET Framework",
821824
"docs/framework/data/adonet/**/*.md": "ADO.NET",

docs/csharp/includes/field-preview.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ ms.date: 10/30/2024
88
> [!IMPORTANT]
99
>
1010
> The `field` keyword is a preview feature in C# 13. You must be using .NET 9 and set your `<LangVersion>` element to `preview` in your project file in order to use the `field` contextual keyword.
11+
>
12+
> You should be careful using the `field` keyword feature in a class that has a field named `field`. The new `field` keyword shadows a field named `field` in the scope of a property accessor. You can either change the name of the `field` variable, or use the `@` token to reference the `field` identifier as `@field`. You can learn more by reading the feature specification for [the `field` keyword](~/_csharplang/proposals/field-keyword.md).

docs/csharp/programming-guide/classes-and-structs/auto-implemented-properties.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@ helpviewer_keywords:
1212

1313
Automatically implemented properties make property-declaration more concise when no other logic is required in the property accessors. They also enable client code to create objects. When you declare a property as shown in the following example, the compiler creates a private, anonymous backing field that can only be accessed through the property's `get` and `set` accessors. `init` accessors can also be declared as automatically implemented properties.
1414

15-
## Example
16-
1715
The following example shows a simple class that has some automatically implemented properties:
1816

1917
:::code language="csharp" source="./snippets/properties/AutoImplemented.cs" id="Snippet28":::
2018

21-
You can't declare automatically implemented properties in interfaces. Automatically implemented properties declare a private instance backing field, and interfaces can't declare instance fields. Declaring a property in an interface without defining a body declares a property with accessors that must be implemented by each type that implements that interface.
19+
You can't declare automatically implemented properties in interfaces. Automatically implemented and field backed properties declare a private instance backing field, and interfaces can't declare instance fields. Declaring a property in an interface without defining a body declares a property with accessors. Each type that implements that interface must implement that property.
2220

2321
You can initialize automatically implemented properties similarly to fields:
2422

@@ -34,7 +32,24 @@ The class that is shown in the previous example is mutable. Client code can chan
3432

3533
For more information, see [How to implement a lightweight class with automatically implemented properties](./how-to-implement-a-lightweight-class-with-auto-implemented-properties.md).
3634

37-
TODO: Add `field` backed properties to make the slope smooth.
35+
You might need to add validation to an automatically implemented property. C# 13 adds [field backed properties](../../language-reference/keywords/field.md) as a preview feature. You use the `field` keyword to access the compiler generated backing field of an automatically implemented property. For example, you could ensure that the `FirstName` property in the preceding example can't be set to `null` or the empty string:
36+
37+
```csharp
38+
public string FirstName
39+
{
40+
get;
41+
set
42+
{
43+
field = ((string.IsNullOrWhiteSpace(value) == false)
44+
? value
45+
: throw new ArgumentException(nameof(value), "First name can't be whitespace or null"));
46+
}
47+
} = "Jane";
48+
```
49+
50+
This feature enables you to add logic to accessors without requiring you to explicitly declare the backing field. You use the `field` keyword to access the backing field generated by the compiler.
51+
52+
[!INCLUDE[field-preview](../../includes/field-preview.md)]
3853

3954
## See also
4055

docs/csharp/programming-guide/classes-and-structs/partial-classes-and-methods.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Partial Classes and Methods"
33
description: Partial classes and methods in C# split the definition of a class, a struct, an interface, or a method over two or more source files.
4-
ms.date: 08/20/2024
4+
ms.date: 10/31/2024
55
helpviewer_keywords:
66
- "partial methods [C#]"
77
- "partial classes [C#]"
@@ -116,6 +116,14 @@ The method and all calls to the method are removed at compile time when there's
116116

117117
Any method that doesn't conform to all those restrictions, including properties and indexers, must provide an implementation. That implementation might be supplied by a *source generator*. [Partial properties](../../language-reference/keywords/partial-member.md) can't be implemented using automatically implemented properties. The compiler can't distinguish between an automatically implemented property, and the declaring declaration of a partial property.
118118

119+
Beginning with C# 13, the implementing declaration for a partial property can use [field backed properties](../../language-reference/keywords/field.md) to define the implementing declaration. A field backed property provides a concise syntax where the `field` keyword accesses the compiler generated backing field for the property. For example, you could write the following:
120+
121+
:::code language="csharp" source="snippets/partial-classes-and-methods/Program.cs" id="FieldProperty":::
122+
123+
You can use `field` in either the `get` or `set` accessor, or both.
124+
125+
[!INCLUDE[field-preview](../../includes/field-preview.md)]
126+
119127
Partial methods enable the implementer of one part of a class to declare a member. The implementer of another part of the class can define that member. There are two scenarios where this separation is useful: templates that generate boilerplate code, and source generators.
120128

121129
- **Template code**: The template reserves a method name and signature so that generated code can call the method. These methods follow the restrictions that enable a developer to decide whether to implement the method. If the method isn't implemented, then the compiler removes the method signature and all calls to the method. The calls to the method, including any results that would occur from evaluation of arguments in the calls, have no effect at run time. Therefore, any code in the partial class can freely use a partial method, even if the implementation isn't supplied. No compile-time or run-time errors result if the method is called but not implemented.
@@ -140,7 +148,7 @@ partial void OnNameChanged()
140148

141149
## C# Language Specification
142150

143-
For more information, see [Partial types](~/_csharpstandard/standard/classes.md#1527-partial-declarations) and [Partial methods](~/_csharpstandard/standard/classes.md#1569-partial-methods) in the [C# Language Specification](~/_csharpstandard/standard/README.md). The language specification is the definitive source for C# syntax and usage. The additional features for partial methods are defined in the [feature specification](~/_csharplang/proposals/csharp-9.0/extending-partial-methods.md).
151+
For more information, see [Partial types](~/_csharpstandard/standard/classes.md#1527-partial-declarations) and [Partial methods](~/_csharpstandard/standard/classes.md#1569-partial-methods) in the [C# Language Specification](~/_csharpstandard/standard/README.md). The language specification is the definitive source for C# syntax and usage. The new features for partial methods are defined in the [feature specification](~/_csharplang/proposals/csharp-9.0/extending-partial-methods.md).
144152

145153
## See also
146154

docs/csharp/programming-guide/classes-and-structs/properties.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ You can initialize a property to a value other than the default by setting a val
2626

2727
:::code language="csharp" source="./snippets/properties/Person.cs" id="Initializer":::
2828

29+
## Field backed properties
30+
31+
In C# 13, you can add validation or other logic in the accessor for a property using the [`field`](../../language-reference/keywords/field.md) keyword preview feature. The `field` keyword accesses the compiler generated backing field for a property. It enables you to write a property accessor without explicitly declaring a separate backing field.
32+
33+
:::code language="csharp" source="./snippets/properties/Person.cs" id="FieldBackedProperty":::
34+
35+
[!INCLUDE[field-preview](../../includes/field-preview.md)]
36+
2937
## Required properties
3038

3139
The preceding example allows a caller to create a `Person` using the default constructor, without setting the `FirstName` property. The property changed type to a *nullable* string. Beginning in C# 11, you can *require* callers to set a property:
@@ -39,10 +47,6 @@ The preceding code makes two changes to the `Person` class. First, the `FirstNam
3947
4048
:::code language="csharp" source="./snippets/properties/Program.cs" id="SnippetInitialize":::
4149

42-
## Field backed properties
43-
44-
TODO: `field` discussion
45-
4650
## Expression body definitions
4751

4852
Property accessors often consist of single-line statements. The accessors assign or return the result of an expression. You can implement these properties as expression-bodied members. Expression body definitions consist of the `=>` token followed by the expression to assign to or retrieve from the property.

docs/csharp/programming-guide/classes-and-structs/snippets/partial-classes-and-methods/PartialClassesAndMethods.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net8.0</TargetFramework>
5+
<TargetFramework>net9.0</TargetFramework>
66
<Nullable>enable</Nullable>
77
<ImplicitUsings>enable</ImplicitUsings>
88
<RootNamespace>PartialClassesAndMethods</RootNamespace>
99
<StartupObject>WrapCoords2.TestCoords</StartupObject>
10+
<LangVersion>preview</LangVersion>
1011
</PropertyGroup>
1112

1213
</Project>

docs/csharp/programming-guide/classes-and-structs/snippets/partial-classes-and-methods/Program.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,20 @@ partial struct S1
165165
void Struct_Test2() { }
166166
}
167167
//</Snippet10>
168+
169+
// <FieldProperty>
170+
// in file1.cs
171+
public partial class Container
172+
{
173+
// Defining declaration
174+
public int MyProperty { get; set; }
175+
}
176+
177+
// In file2.cs
178+
public partial class Container
179+
{
180+
// Defining declaration
181+
public int MyProperty { get => field; set; }
182+
}
183+
184+
// </FieldProperty>

docs/csharp/programming-guide/classes-and-structs/snippets/properties/Person.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,22 @@ public class Person
2424
// </AutoImplemented>
2525
}
2626

27+
namespace VersionTwoPointFive
28+
{
29+
// <FieldBackedProperty>
30+
public class Person
31+
{
32+
public string? FirstName
33+
{
34+
get;
35+
set => field = value.Trim();
36+
}
37+
38+
// Omitted for brevity.
39+
}
40+
// </FieldBackedProperty>
41+
}
42+
2743
namespace VersionThree
2844
{
2945
// <Initializer>

docs/csharp/programming-guide/classes-and-structs/snippets/properties/TimePeriod.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,20 @@ public int Month
1818
}
1919
}
2020
//</UsingExample>
21+
22+
//<FieldExample>
23+
public class DateExample
24+
{
25+
public int Month
26+
{
27+
get;
28+
set
29+
{
30+
if ((value > 0) && (value < 13))
31+
{
32+
field = value;
33+
}
34+
}
35+
}
36+
}
37+
//</FieldExample>

docs/csharp/programming-guide/classes-and-structs/snippets/properties/properties.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net8.0</TargetFramework>
5+
<TargetFramework>net9.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
8+
<LangVersion>preview</LangVersion>
89
</PropertyGroup>
910

1011
</Project>

0 commit comments

Comments
 (0)