C #: литерал по умолчанию и вывод типа для обнуляемых структур

#c# #nullable #c#-7.1

#c# #обнуляемый #c #-7.1

Вопрос:

Начиная с C # 7.1, можно получать значения по умолчанию с помощью default без указания типа. Я попробовал это сегодня и обнаружил, что результаты для обнуляемых структур и типов значений с обнуляемыми значениями несколько противоречат интуиции.

 [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"

    }
}
  

Я бы ожидал, что myDefaultAge будет null , а не 0 , потому что myAge имеет тип int? и default(int?) является null .

Указано ли где-нибудь такое поведение? В руководстве по программированию на C # сказано только, что «Литерал по умолчанию выдает то же значение, что и эквивалентное значение по умолчанию (T), где T — предполагаемый тип».

Комментарии:

1. var myDefaultAge = myAge ?? defau< в чем смысл этой строки? Вы проверяете, myAge не равно null, следовательно, этого не может быть null , поэтому значение по умолчанию будет default(int) . Вы можете вручную указать с помощью var myDefaultAge = myAge ?? default(int?); или просто var myDefaultAge = myAge;

2. @SeM Я бы предположил, что это делается для того, чтобы показать несоответствие.

3. Это строка с неожиданным поведением 🙂 Мой вопрос не столько о реальной полезности, сколько о выполнении ожиданий и о том, что он где-то указан (и, следовательно, рассчитан на будущее)

Ответ №1:

Это задокументировано для оператора объединения с нулем:

Тип выражения a ?? b зависит от того, какие неявные преобразования доступны для операндов. В порядке предпочтения, тип a ?? b — это A0, A или B, где A — тип a (при условии, что a имеет тип), B — тип b (при условии, что b имеет тип), а A0 — базовый тип A, если A — обнуляемый тип

Точно описывает нашу ситуацию здесь — A является обнуляемым, default не имеет типа.