csharp-language-server-protocol icon indicating copy to clipboard operation
csharp-language-server-protocol copied to clipboard

Container<T>.implicit operator(T[]) does not accept null, but is implemented to handle it

Open jimmylewis opened this issue 4 years ago • 0 comments

Code for context:

[return: NotNullIfNotNull("items")]
public static implicit operator Container<T>?(T[] items) => items switch {
    not null => new Container<T>(items),
    _        => null
};

The annotation only accepts a non-null T[], so the _ branch of the switch cannot be used (assuming the caller is adhering to the annotated requirement).

However, this causes annoying workarounds when constructing objects where the value could be null, e.g:

string[]? commitCharacters = SomeCalculation();
CompletionItem c = new CompletionItem()
{
    ...,
    // error CS8604: Possible null reference argument for parameter 'items' in 'Container<string>.implicit operator Container<string>?(string[] items)'.
    CommitCharacters = commitCharacters,
    // alternatively, this can be written inconveniently as:
    CommitCharacters = commitCharacters ?? (Container<string>)null; // cast required to tell the compiler it isn't (string[])null
}

The same issue exists for the constructor, which prevents using new Container<string>(commitCharacters) either.

jimmylewis avatar Oct 07 '21 04:10 jimmylewis