You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add additional examples where appropriate in the What's new in C# 13 article.
Also, pick up some additional meta data bits that have been missing in our docfx.
Fixes#42683
Copy file name to clipboardExpand all lines: docs/csharp/whats-new/csharp-13.md
+60-6Lines changed: 60 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
---
2
2
title: What's new in C# 13
3
3
description: Get an overview of the new features in C# 13. Follow the release of new preview features as .NET 9 and C# 13 previews are released.
4
-
ms.date: 08/20/2024
4
+
ms.date: 09/30/2024
5
5
ms.topic: whats-new
6
6
---
7
7
# What's new in C# 13
@@ -35,12 +35,28 @@ The `params` modifier isn't limited to array types. You can now use `params` wit
35
35
36
36
When an interface type is used, the compiler synthesizes the storage for the arguments supplied. You can learn more in the feature specification for [`params` collections](~/_csharplang/proposals/csharp-13.0/params-collections.md).
37
37
38
+
For example, method declarations can declare spans as `params` parameters:
39
+
40
+
```csharp
41
+
publicvoidConcat<T>(paramsReadOnlySpan<T>items)
42
+
{
43
+
for (inti=0; i<items.Length; i++)
44
+
{
45
+
Console.Write(items[i]);
46
+
Console.Write("");
47
+
}
48
+
Console.WriteLine();
49
+
}
50
+
```
51
+
38
52
## New lock object
39
53
40
54
The .NET 9 runtime includes a new type for thread synchronization, the <xref:System.Threading.Lock?displayProperty=fullName> type. This type provides better thread synchronization through its API. The <xref:System.Threading.Lock.EnterScope?displayProperty=nameWithType> method enters an exclusive scope. The `ref struct` returned from that supports the `Dispose()` pattern to exit the exclusive scope.
41
55
42
56
The C# [`lock`](../language-reference/statements/lock.md) statement recognizes if the target of the lock is a `Lock` object. If so, it uses the updated API, rather than the traditional API using <xref:System.Threading.Monitor?displayProperty=nameWithType>. The compiler also recognizes if you convert a `Lock` object to another type and the `Monitor` based code would be generated. You can read more in the feature specification for the [new lock object](~/_csharplang/proposals/csharp-13.0/lock-object.md).
43
57
58
+
This feature allows you to get the benefits of the new library type by changing the type of object you `lock`. No other code needs to change.
59
+
44
60
## New escape sequence
45
61
46
62
You can use `\e` as a [character literal](~/_csharpstandard/standard/lexical-structure.md#6455-character-literals) escape sequence for the `ESCAPE` character, Unicode `U+001B`. Previously, you used `\u001b` or `\x1b`. Using `\x1b` wasn't recommended because if the next characters following `1b` were valid hexadecimal digits, those characters became part of the escape sequence.
@@ -80,6 +96,8 @@ The preceding example creates an array that counts down from 9 to 0. In versions
80
96
81
97
## `ref` and `unsafe` in iterators and `async` methods
82
98
99
+
This feature and the following two features enable `ref struct` types to use new constructs. You won't use these unless you write your own `ref struct` types. More likely, you'll see an indirect benefit as <xref:System.Span`1?displayProperty=nameWithType> and <xref:System.ReadOnlySpan`1?displayProperty=nameWithType> gain more functionality.
100
+
83
101
Before C# 13, iterator methods (methods that use `yield return`) and `async` methods couldn't declare local `ref` variables, nor could they have an `unsafe` context.
84
102
85
103
In C# 13, `async` methods can declare `ref` local variables, or local variables of a `ref struct` type. However, those variables can't be accessed across an `await` boundary. Neither can they be accessed across a `yield return` boundary.
@@ -88,19 +106,55 @@ This relaxed restriction enables the compiler to allow verifiably safe use of `r
88
106
89
107
In the same fashion, C# 13 allows `unsafe` contexts in iterator methods. However, all `yield return` and `yield break` statements must be in safe contexts.
90
108
91
-
## `ref struct` interfaces
92
-
93
-
Before C# 13, `ref struct` types weren't allowed to implement interfaces. Beginning with C# 13, they can. To ensure ref safety rules, a `ref struct` type can't be converted to an interface type. That is a boxing conversion, and could violate ref safety. Learn more in the updates on [`ref struct` types](../language-reference/builtin-types/ref-struct.md#restrictions-for-ref-struct-types-that-implement-an-interface).
94
-
95
109
## `allows ref struct`
96
110
97
111
Before C# 13, `ref struct` types couldn't be declared as the type argument for a generic type or method. Now, generic type declarations can add an anti-constraint, `allows ref struct`. This anti-constraint declares that the type argument supplied for that type parameter can be a `ref struct` type. The compiler enforces ref safety rules on all instances of that type parameter.
98
112
113
+
For example, you may declare an interface like the following code:
114
+
115
+
```csharp
116
+
publicclassC<T> whereT : allowsrefstruct
117
+
{
118
+
// Use T as a ref struct:
119
+
publicvoidM(scopedT p)
120
+
{
121
+
// The parameter p must follow ref safety rules
122
+
}
123
+
}
124
+
```
125
+
99
126
This enables types such as <xref:System.Span%601?displayProperty=nameWithType> and <xref:System.ReadOnlySpan%601?displayProperty=nameWithType> to be used with generic algorithms, where applicable. You can learn more in the updates for [`where`](../language-reference/keywords/where-generic-type-constraint.md) and the programming guide article on [generic constraints](../programming-guide/generics/constraints-on-type-parameters.md).
100
127
128
+
## `ref struct` interfaces
129
+
130
+
Before C# 13, `ref struct` types weren't allowed to implement interfaces. Beginning with C# 13, they can. You can declare that a `ref struct` type implements interfaces. However, to ensure ref safety rules, a `ref struct` type can't be converted to an interface type. That is a boxing conversion, and could violate ref safety. From that rule, `ref struct` types can't declare methods that explicitly implement an interface method. Also, `ref struct` types must implement all methods declared in an interface, including those with a default implementation.
131
+
132
+
Learn more in the updates on [`ref struct` types](../language-reference/builtin-types/ref-struct.md#restrictions-for-ref-struct-types-that-implement-an-interface).
133
+
101
134
## More partial members
102
135
103
-
You can declare `partial` properties and `partial` indexers in C# 13. Partial properties and indexers generally follow the same rules as `partial` methods: you create one *declaring declaration* and one *implementing declaration*. The signatures of the two declarations must match. One restriction is that you can't use an auto-property declaration for a partial property. Properties that don't declare a body are considered the *declaring declaration*. You can learn more in the article on [partial members](../language-reference/keywords/partial-member.md).
136
+
You can declare `partial` properties and `partial` indexers in C# 13. Partial properties and indexers generally follow the same rules as `partial` methods: you create one *declaring declaration* and one *implementing declaration*. The signatures of the two declarations must match. One restriction is that you can't use an auto-property declaration for a partial property. Properties that don't declare a body are considered the *declaring declaration*.
137
+
138
+
```csharp
139
+
publicpartialclassC
140
+
{
141
+
// Declaring declaration
142
+
publicpartialstringName { get; set; }
143
+
}
144
+
145
+
publicpartialclassC
146
+
{
147
+
// implementation declaration:
148
+
privatestring_name;
149
+
publicpartialstringName
150
+
{
151
+
get=>_name;
152
+
set=>_name=value;
153
+
}
154
+
}
155
+
```
156
+
157
+
You can learn more in the article on [partial members](../language-reference/keywords/partial-member.md).
0 commit comments