I'm updating my code to C# 12 and one aspect is to use primary constructors where it makes sense.
One place that's giving me a bit of a struggle is inside a ref
struct which takes a ReadOnlySpan
as a constructor argument, which is itself a ref
struct. If I use a primary constructor here, I get an error when I try to access value
inside an instance method:
/// <summary>An utility like String.Split, but for Spans. This should avoid allocations.</summary>
internal ref struct CharSpanSplitter(ReadOnlySpan<char> value, char separator)
{
// Uncomment to make the error go away
//private ReadOnlySpan<char> value = value;
public ReadOnlySpan<char> Current { get; private set; }
public bool MoveNext()
{
// CS9110: Cannot use primary constructor parameter that has ref-like type inside an instance member.
if (value == ReadOnlySpan<char>.Empty)
{
return false;
}
// CS9110: Cannot use primary constructor parameter that has ref-like type inside an instance member.
var index = value.IndexOf(separator);
if (index == -1)
{
// CS9110: Cannot use primary constructor parameter that has ref-like type inside an instance member.
Current = value;
// CS9110: Cannot use primary constructor parameter that has ref-like type inside an instance member.
value = ReadOnlySpan<char>.Empty;
return true;
}
// CS9110: Cannot use primary constructor parameter that has ref-like type inside an instance member.
Current = value[..index];
// CS9110: Cannot use primary constructor parameter that has ref-like type inside an instance member.
value = value[(index + 1)..];
return true;
}
}
This is rather new stuff so a google search for CS9110 didn't really give me useful results. Does anyone know why what I'm trying to do is not allowed?
You may also note on line 5 there is a commented out private field for storing a reference to the primary constructor argument. If I uncommented it, all the CS9110 errors disappear. What's going on there?
To answer my own question, it's a limitation of the design, per this paragraph from the proposal:
https://github.com/dotnet/csharplang/blob/main/proposals/csharp-12.0/primary-constructors.md#semantics