I was just playing with the new readonly struct features of C# 7.2. To check if things got faster I first declared a new struct
readonly struct FastPoint { public int X { get; set; } public int Y { get; set; } }
But Visual Studio will then complain
Program.cs(12,20,12,21): error CS8341: Auto-implemented instance properties in readonly structs must be readonly.
Program.cs(13,20,13,21): error CS8341: Auto-implemented instance properties in readonly structs must be readonly.
Ok. No problem lets make the setter private. But the error stays. Perhaps I need to add some modifier to the get property. Lets try readonly
public int X { readonly get; private set; }
This results in
error CS0106: The modifier ‘readonly’ is not valid for this item
Ok. Now I am desperate. Lets try ref readonly. Hah something happens:
But not for the better. VS eats up all the memory and if you try to compile it will transfer the leak into PerfWatson2.exe as well.
Ok that was not it. The final solution was to remove the setter completely. Interestingly you can still set the property although it has no declared setter.
readonly struct FastPoint { public int X { get; } public int Y { get; } public FastPoint(int x, int y) { X = x; Y = y; } }
This seems to be a C# 6 feature I was until now not aware of. Problem solved. But wait what was the ever increasing memory of the compiler?
From the call stacks we can deduce quite a bit
Roslyn is parsing a property declaration and has found ref which is a valid token. Now some memory is allocated for the token but later is treated as wrong token. That in itself would not be too bad but it seems that the parser seems to rewind and then tries parsing the same wrong property declaration again which results in infinite memory consumption. I have reported the issue here
which will hopefully be fixed. The error message is ok in hindsight but it did confuse me the first time. If you want to play with the newest C# features you need to open the build properties tab, press Advanced and then you can select the e.g. C# latest minor version to always use the latest C# version.
Lets hope you are not hitting new memory leaks as fast as I did.