-
C# 12 features: ref readonly
Part 3 in a series on new language features in C# 12.
ref readonly
modifierA bit more of a niche feature - if you have code that is passing structs by
ref
, but you don't need to (or want to) allow modification of the parameter, you can now indicate it is readonly.public static void ByRefReadonly(ref readonly Point p) { //p = new Point(2, 3); Console.WriteLine(p); }
In the code sample above,
Point
is a struct or record type. If you uncommented the line then the compiler will emit an error.Interesting, but I've not come across a need to use this yet.
Further reading
Example source
https://github.com/flcdrg/csharp-12/blob/main/02-collection-expressions/CollectionExpressions.cs
-
C# 12 features: Collection expressions
Part 2 in a series on new language features in C# 12.
Collection expressions
You can now use square brackets
[]
to initialise a collection! Usually square brackets indicate an array, but the collection expression can be assigned to other collection types too.You can use them to assign values to fields or in method bodies.
private List<int> numbersList = [1, 2, 3, 4, 5];
Like primary constructors, I've also found these quite useful in new .NET 8 projects.
Further reading
Example source
https://github.com/flcdrg/csharp-12/blob/main/02-collection-expressions/CollectionExpressions.cs
-
C# 12 features: Primary constructors
Last month, we had a ".NET 8 Lightning talks" theme for the Adelaide .NET User Group. John covered Blazor, Ryan summarised a bunch of new core library features, and I focused on the 8 new language features added in C# 12. What a great idea for a nice, short blog series!
Primary constructors
C# has had primary constructors for records, but now we can use them for classes and structs!
The parameters can be used anywhere within the class - methods, local functions as well as initialising fields and properties.
A primary constructor guarantees that the named parameters have been supplied when an instance is created. You can optionally add other conventional constructors, but they must all call back to the primary constructor using the
this(...)
syntax.public class PrimaryConstructorClass(string name) { private string Name { get; init; } = name; private string Name2 => name; public void Thing() { Console.WriteLine(name); } }
I've made regular use of these whenever I've been working on a .NET 8 project. I've found them very useful.
Further reading
Example source
https://github.com/flcdrg/csharp-12/tree/main/01-primary-constructors