С # 8.0 возвращаемый тип выражения переключения и нулевое значение

Я пытаюсь понять, как работают выражения переключателя C# 8.0, и у меня есть несколько вопросов.

  1. Почему нельзя использовать nullзначение в случае по умолчанию? Компилятор бросаетCannot convert null to 'int' because it is a non-nullable value type ошибка.
  2. Почему он пытается преобразовать нулевое значение в int а тип возвращаемого значения функции - double?

Вот функция, с которой я играю:

public static double? SwitchFunction(int x) =>
    x switch
    {
        1 => 1,
        _ => null
    };

3 ответа

Решение

В выражении переключателя все возможные значения должны быть (неявно приводимые к) одного и того же типа. Потому что ваш первый случай1 => 1, и вы не приводите целочисленный литерал к другому типу, кроме int, остальные случаи будем считать intтакже. Вам нужно будет преобразовать это 1 в(double?) чтобы компилятор интерпретировал остальные случаи также как double?, тип, допускающий значение NULL - это решит обе ваши точки.

Вы столкнулись с проблемой, которая обычно встречается в условном выражении.

// Compiler Error CS0173
// Type of conditional expression cannot be determined because 
// there is no implicit conversion between 'int' and '<null>'
//
// var d2 = i == 1 ? 1 : null; 

// This works
var d2 = i == 1 ? 1 : (double?) null;

Чтобы решить проблему в switch выражение, вы можете помочь компилятору, указав тип null является.

int i = 2;
var d = i switch
{
    1 => 1,
    _ => (double?)null
};

Я столкнулся с той же проблемой, что привело к другому сообщению об ошибке: "Не найден лучший тип для выражения переключения".

var isRequired = someIntValue switch
    {
      0 => null,
      1 => false,
      2 => true,
      _ => throw new NotSupportedException(),
    };

Я не мог понять это сообщение об ошибке, пока не прочитал здесь ответы. Компилятор не может определить, каким должен быть тип isRequired. Мое намерение было bool?. При изменении кода на это сообщение об ошибке исчезает:

var isRequired = someIntValue switch
    {
      0 => (bool?)null,
      1 => false,
      2 => true,
      _ => throw new NotSupportedException(),
    };

С другой стороны, я мог просто сказать компилятору, что хочу:

bool? isRequired = someIntValue switch
    {
      0 => null,
      1 => false,
      2 => true,
      _ => throw new NotSupportedException(),
    };

Я читал на GitHub, что они намерены исправить это в будущей версии.

Другие вопросы по тегам