Каково обоснование такого поведения Nullable с неявными операторами преобразования

Я столкнулся с интересным поведением во взаимодействии между Nullableи неявными преобразованиями. Я обнаружил, что предоставление неявного преобразования для ссылочного типа из типа значения позволяет передать тип Nullableв функцию, требующую ссылочного типа, когда вместо этого я ожидаю ошибки компиляции. Код ниже демонстрирует это:

static void Main(string[] args)
{
    PrintCatAge(new Cat(13));
    PrintCatAge(12);
    int? cat = null;
    PrintCatAge(cat);
}

private static void PrintCatAge(Cat cat)
{
    if (cat == null)
        System.Console.WriteLine("What cat?");
    else
        System.Console.WriteLine("The cat's age is {0} years", cat.Age);
}

class Cat
{
    public int Age { get; set; }
    public Cat(int age)
    {
        Age = age;
    }

    public static implicit operator Cat(int i)
    {
        System.Console.WriteLine("Implicit conversion from " + i);
        return new Cat(i);
    }
}

Вывод:

The cat's age is 13 years
Implicit conversion from 12
The cat's age is 12 years
What cat?

Если код преобразования удален из Cat, вы получите ожидаемые ошибки:

Ошибка 3 Лучший перегруженный метод, соответствующий 'ConsoleApplication2.Program .PrintCatAge(ConsoleApplication2.Program.Cat) имеет недопустимые аргументы

Ошибка 4. Аргумент 1: невозможно преобразовать из 'int?' на 'ConsoleApplication2.Program.Cat

Если вы откроете исполняемый файл с помощью ILSpy, будет сгенерирован следующий код.

int? num = null;
Program.PrintCatAge(num.HasValue ? num.GetValueOrDefault() : null);

В аналогичном эксперименте я удалил преобразование и добавил перегрузку к PrintCatAge, которая принимает целое число (не допускающее значение NULL) в посмотрите, выполнит ли компилятор подобную операцию, но он этого не делает.

Я понимаю, что происходит, но не понимаю оправдания этому. Такое поведение для меня неожиданно и кажется странным. Мне не удалось найти какие-либо ссылки на это поведение в MSDN в документации по преобразованиям или Nullable.

Вопрос, который я задаю, заключается в том, является ли это намеренным и есть ли объяснение, почему это происходит?

32
задан BoltClock 16 April 2012 в 23:35
поделиться