3

Since C# 7.1, it is possible to get default values by using default without specifying the type. I tried it out today and found the results for nullable structs and nullable value types somewhat counterintuitive.

[TestFixture]
public class Test
{
    private class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

    [Test]
    public void ShouldBehaveAsExpected()
    {
        var person1 = new Person {Name = "John", Age = 58};
        var person2 = new Person {Name = "Tina", Age = 27};

        var persons = new[] {person1, person2};

        int? myAge = persons.FirstOrDefault(p => p.Name == "MyName")?.Age;
        var myDefaultAge = myAge ?? default;

        var myAgeString = myAge == null ? "null" : myAge.ToString();
        var myDefaultAgeString = myDefaultAge == null ? "null" : myDefaultAge.ToString();

        Console.WriteLine("myAge: " + myAgeString);                 // "myAge: null"
        Console.WriteLine("myDefaultAge: " + myDefaultAgeString);   // "myDefaultAge: 0"

    }
}

I would have expected myDefaultAge to be null rather than 0, because myAge is of type int? and default(int?) is null.

Is this behaviour specified anywhere? The C# programming guide only says that " The default literal produces the same value as the equivalent default(T) where T is the inferred type."

Jan
  • 241
  • 1
  • 6
  • 1
    `var myDefaultAge = myAge ?? default;` what is the point of this line? You are checking if `myAge` is not null, therefore it can't be `null`, so the default will be `default(int)`. You can manually specify by `var myDefaultAge = myAge ?? default(int?);` or just `var myDefaultAge = myAge;` – Sá´‡M Mar 14 '19 at 08:54
  • 1
    @SeM I would imagine it's there to show the discrepancy. – Matthew Watson Mar 14 '19 at 08:57
  • This is the line with the unexpected behaviour :) My question is not so much about real-world usefulness, but about fulfilling expectations and about being specified somewhere (and thus future-proof) – Jan Mar 14 '19 at 08:59

1 Answers1

6

It's documented for the null-coalescing operator:

The type of the expression a ?? b depends on which implicit conversions are available on the operands. In order of preference, the type of a ?? b is A0, A, or B, where A is the type of a (provided that a has a type), B is the type of b (provided that b has a type), and A0 is the underlying type of A if A is a nullable type

Precisely describes our situation here - A is nullable, default doesn't have a type.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448