|<<>>|1 of 283 Show listMobile Mode

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.

  1. Completely unsurprisingly, the params keyword now also applies to IEnumerable<T> (as well as many descendants) as well as Span<T> and ReadOnlySpan<T>.
  2. There’s now an official Lock object that, when used instead of the standard object, can lead to more efficient locking code. The .NET runtime and BCL have already starting using this ref struct everywhere.
  3. 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 represents ESCAPE. Um, ok.
  4. 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.
  5. 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.
  6. “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, all yield return and yield break statements must be in safe contexts.”

  7. 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?
  8. The language now supports the allows ref struct (anti-)generic constraint. “This enables types such as System.Span<T> and System.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.
  9. Finally, “you can declare partial properties and partial indexers”. Expanding support for partial enables more flexibility in code produced by source generators.