Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET non-nullable reference type and out parameters

I modified my csproj file to enable null reference types in C#8:

<Nullable>enable</Nullable>

Given the following code:

private static void Method()
{
    var dictionary = new Dictionary<string, string>();
    string value = string.Empty;

    dictionary.TryGetValue("Key", out value);
}

The line with TryGetValue() gives the warning:

CS8600: Converting null literal or possible null value to non-nullable type.

I don't understand why. The signature of TryGetValue() is :

public bool TryGetValue(string key, [MaybeNullWhen(false)] out string value);

The code example has only non-nullable references. Why is it getting this error?

like image 990
vernou Avatar asked Feb 21 '26 09:02

vernou


2 Answers

If "Key" isn't found in the dictionary, then a value of null will be assigned to the value variable. However you've declared value as string, meaning that it shouldn't contain null. Therefore the compiler is giving you a warning.

The fact that you've initially assigned string.Empty to value doesn't matter - that will always get overwritten by TryGetValue (and you should get another warning which says that).

You should declare value as a string?, to indicate that its value might be null.

Note that the compiler's pretty smart. If you write:

if (!dictionary.TryGetValue("Key", out string? value))
{
    value = string.Empty;
}

then the compiler knows that value cannot be null, and it won't complain if you then try and call methods on it.

like image 106
canton7 Avatar answered Feb 22 '26 22:02

canton7


canton7's answer is correct (+1).
This is not an explanation but a workaround:
You could add an extension method to Dictionary<TVey, TValue> like this:

public static bool TryGetValue<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue @default, out TValue @value) where TKey : notnull
{
    var result = dictionary.TryGetValue(key, out var val);
    @value = result ? val : @default;
    return result;
}

Then you can use it like this:

private static void Method()
{
    var dictionary = new Dictionary<string, string>();
    /// populate dictionary here...

    dictionary.TryGetValue("Key", string.Empty, out var value);
}

This should enable you to keep value as a non-nullable string.

like image 35
Zohar Peled Avatar answered Feb 22 '26 22:02

Zohar Peled



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!