1

I am having a hard time understanding how nullable value types works in C#9.

Following documentation from:

I can write (no compiler error):

int? a = 10;
a++; // No need for explicit 'a.Value'

But I cannot write (compiler error):

Span<char> TryFormatOrNull(int? input)
{
    char[] buffer = new char[512];
    if (input == null) return null;
    _ = input.TryFormat(buffer, out _);
    return buffer;
}

I need to write (no syntaxic sugar):

Span<char> TryFormatOrNull(int? input)
{
    char[] buffer = new char[512];
    if (input == null) return null;
    _ = input.Value.TryFormat(buffer, out _);
    return buffer;
}

What did I misunderstood with nullable value types vs member function/operator ?

malat
  • 12,152
  • 13
  • 89
  • 158
  • 2
    As an aside, you shouldn't need the `!` in the second version, as the compiler should "know" that it's not null by that point. – Jon Skeet Sep 08 '21 at 08:33

2 Answers2

6

What did I misunderstood with nullable value types vs member function/operator ?

That operators are automatically "lifted" (i.e. the operators for the non-nullable value type are automatically made available for the corresponding nullable value type) but methods aren't. That's all, really.

See section 12.4.8 of the C# standard for details of lifted operators, and 11.6.2 for lifted conversions.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I am guessing there is a good reason for this. Do you know why ? – malat Sep 08 '21 at 08:33
  • 1
    @malat: Aside from anything else, the designers know that `Nullable` doesn't have any operators defined on it directly - but it *does* have methods. If the non-nullable T declared some methods that were also on `Nullable`, that could be really confusing. Additionally, the behavior of the operators is pretty easy to specify in terms of what happens if the value is null - that's not the case for methods (where there can be out parameters etc). – Jon Skeet Sep 08 '21 at 08:35
  • 2
    @malat If it worked that way, would `someNullableInt.GetType()` return `Nullable` or `int`? – Sweeper Sep 08 '21 at 08:36
3

This is happening because ++ is a predefined unary operator which can be "lifted" (while TryFormat method is not):

The predefined unary and binary operators or any overloaded operators that are supported by a value type T are also supported by the corresponding nullable value type T?. These operators, also known as lifted operators, produce null if one or both operands are null; otherwise, the operator uses the contained values of its operands to calculate the result.

Guru Stron
  • 102,774
  • 10
  • 95
  • 132