Skip to content

Commit 4950a32

Browse files
authored
add additional examples (#42763)
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
1 parent b596166 commit 4950a32

File tree

2 files changed

+64
-6
lines changed

2 files changed

+64
-6
lines changed

docfx.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,10 @@
309309
"docs/visual-basic/**/**.md": "vb"
310310
},
311311
"author": {
312+
"_csharplang/**/*.md": "billwagner",
313+
"_csharpstandard/**/*.md": "billwagner",
314+
"_roslyn/docs/compilers/CSharp/*.md": "billwagner",
315+
"_vblang/spec/*.md": "billwagner",
312316
"docs/azure/**/*.*": "alexwolfmsft",
313317
"docs/orleans/**/*.*": "IEvangelist",
314318
"docs/architecture/**/**.md": "jamesmontemagno",

docs/csharp/whats-new/csharp-13.md

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: What's new in C# 13
33
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
55
ms.topic: whats-new
66
---
77
# 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
3535

3636
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).
3737

38+
For example, method declarations can declare spans as `params` parameters:
39+
40+
```csharp
41+
public void Concat<T>(params ReadOnlySpan<T> items)
42+
{
43+
for (int i = 0; i < items.Length; i++)
44+
{
45+
Console.Write(items[i]);
46+
Console.Write(" ");
47+
}
48+
Console.WriteLine();
49+
}
50+
```
51+
3852
## New lock object
3953

4054
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.
4155

4256
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).
4357

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+
4460
## New escape sequence
4561

4662
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
8096

8197
## `ref` and `unsafe` in iterators and `async` methods
8298

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+
83101
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.
84102

85103
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
88106

89107
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.
90108

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-
95109
## `allows ref struct`
96110

97111
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.
98112

113+
For example, you may declare an interface like the following code:
114+
115+
```csharp
116+
public class C<T> where T : allows ref struct
117+
{
118+
// Use T as a ref struct:
119+
public void M(scoped T p)
120+
{
121+
// The parameter p must follow ref safety rules
122+
}
123+
}
124+
```
125+
99126
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).
100127

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+
101134
## More partial members
102135

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+
public partial class C
140+
{
141+
// Declaring declaration
142+
public partial string Name { get; set; }
143+
}
144+
145+
public partial class C
146+
{
147+
// implementation declaration:
148+
private string _name;
149+
public partial string Name
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).
104158

105159
## Overload resolution priority
106160

0 commit comments

Comments
 (0)