C# 13 improvements
Published by marco on
The final document of What’s new in C# 13 (Microsoft Learn) is available. There are no major changes for most end users; the changes listed are interested for library and framework developers—especially those interested in writing highly performant code, e.g., Microsoft in its BCL and ASP.NET.
- Completely unsurprisingly, the
params
keyword now also applies toIEnumerable<T>
(as well as many descendants) as well asSpan<T>
andReadOnlySpan<T>
. - There’s now an official
Lock
object that, when used instead of the standardobject
, can lead to more efficient locking code. The .NET runtime and BCL have already starting using thisref struct
everywhere. - I am not kidding when I say that the third “feature” in the list is that
\e
is now an accepted escape sequence in all strings. It representsESCAPE
. Um, ok. - Method group and method-group calculation has been improved to more closely follow that for overload resolution, allowing Roslyn to better determine a unique type and to extend where
var
can be safely used. - You can now use the “from the end” index operator,
^
in object and collection initializer expressions. Again, this is an improvement that seems like it makes it easier to write input arrays for numeric (data analysis) or tokenizing (LLM) operations. “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.“[…] You can safely use types like
System.ReadOnlySpan<T>
[…]“In the same fashion, C# 13 allows
unsafe
contexts in iterator methods. However, allyield return
andyield break
statements must be in safe contexts.”ref structs
can now implement interfaces but it’s hard to see the utility because “[t]o ensure ref safety rules, a ref struct type can’t be converted to an interface type.” Um, ok?- The language now supports the
allows ref struct
(anti-)generic constraint. “This enables types such asSystem.Span<T>
andSystem.ReadOnlySpan<T>
to be used with generic algorithms […]” The compiler ensures that the generic code complies with all the rules implied by allowing this more specialized construct. - Finally, “you can declare partial properties and partial indexers”. Expanding support for
partial
enables more flexibility in code produced by source generators.