CS9110: Cannot use primary constructor parameter that has ref-like type inside an instance member. But why not?

373 views Asked by At

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?

1

There are 1 answers

0
Steven Liekens On BEST ANSWER

To answer my own question, it's a limitation of the design, per this paragraph from the proposal:

Capturing is not allowed for parameters that have ref-like type, and capturing is not allowed for ref, in or out parameters. This is similar to a limitation for capturing in lambdas.

https://github.com/dotnet/csharplang/blob/main/proposals/csharp-12.0/primary-constructors.md#semantics