Nullable reference types - return type nullability by the accepted parameter

Viewed 463

I have a method, Foo, that accepts a string. It does something if the string is null and some other thing if it's not (null is a valid value). It then returns the same string.

Here is Foo with nullable reference types disabled in C# 8.0:

string Foo(string s)
{
    // Do something with s.
    return s;
}

void Bar()
{
    string s = "S";
    string s2 = Foo(s);

    string n = null;
    string n2 = Foo(n);
}

After I enable nullable reference types, string n = null gives a warning. This makes sense, since string is not nullable anymore. I convert its type to string?:

void Bar()
{
    string s = "S";
    string s2 = Foo(s);

    string? n = null; // X
    string? n2 = Foo(n);
}

And now Foo(n) warns me about Foo's new dislike of nullable strings. This also makes sense - Foo should accept a nullable string since it supports both null and non-null values. I change its parameter and therefore, return types to string?:

string? Foo(string? s)
{
    // Do something with s.
    return s;
}

This time it's string s2 = Foo(s), complaining about Foo returning a string? and me trying to assign it to a string.

Is there a way for me to let the flow analysis understand the fact that when I'm supplying Foo a string (and not a string?), then its return value cannot be null?

2 Answers

This could make the return value not null when the parameter s is not null.

// using System.Diagnostics.CodeAnalysis;

[return: NotNullIfNotNull("s")]
string? Foo(string? s)
{
    // Do something with s.
    return s;
}

Yes, just have two methods. One that accepts a string? and returns a string?, and another that accepts a string and returns a string. You probably want to implement the former in terms of the latter (check for null, if non-null, call other method, otherwise, handle the null case).

Having two methods is how you ensure that the return type differs based in the input type(s).

Related