Nullable ToString()

Я вижу везде конструкции вроде:

int? myVar = null;
string test = myVar.HasValue ? myVar.Value.ToString() : string.Empty;

Почему бы просто не использовать:

string test = myVar.ToString();

Разве это не то же самое? По крайней мере, Reflector говорит, что:

public override string ToString()
{
  if (!this.HasValue)
  {
    return "";
  }
  return this.value.ToString();
}

Итак, это правильно (более короткая версия) или я что-то упускаю?

Ответ 1

Вы совершенно правы. Также в этот вопрос, первое решение предлагается, пока никто не замечает ToString(), уже дает правильный ответ.

Возможно, аргумент для более подробного решения является читабельностью: когда вы вызываете ToString() на то, что должно быть null, вы обычно ожидаете NullReferenceException, хотя здесь он не выбрасывается.

Ответ 2

Я думаю, что многие люди имеют такие проверки, потому что это не естественное поведение объекта, который может содержать нулевое значение.

Ответ 3

Нет, вы правы, более короткая версия такая же, как и другие люди в этом отношении. Другая конструкция, которую я использую много, вместо тройного с нулевыми значениями, является нулевым коалесцирующим оператором. который также защищает вас от нулей. Для ToString() это необязательно (как вы указали), но по умолчанию значения int (например) работают хорошо, например:

int page = currentPage ?? 1;

который позволяет вам выполнять все операции с целыми числами на странице без первой явно нулевой проверки и вызывать значение в currentPage (где currentPage - это int? возможно, передано как параметр)

Ответ 4

Я знаю, долгое время, когда это было актуально, но... Я подозреваю, что это потому, что для типов с нулевым значением, например int? метод .ToString() не позволяет использовать строки форматирования. См. Как отформатировать нулевую дату DateTime с помощью ToString()?. Возможно, в исходном коде была строка формата в .ToString(), или, возможно, кодер забыл, что .ToString() без строки формата по-прежнему доступна для типов с нулевым значением.

Ответ 5

может быть, это просто следовать шаблону? или они не знают бэкэнда. вы правильный код точно такой же. вы даже можете сделать:

int? i = null;
i.ToString(); //No NullReferenceException

Ответ 6

int? является синтаксическим сахаром, который упрощает объявление переменной NULL. Это то же самое, что и Nullable<int>.

Поэтому, если вы посмотрите на реализацию метода ToString() для Nullable<T> (см. Ниже), вы можете заметить, что он возвращает пустую строку в случае, если он не имеет значения.

public struct Nullable<T> where T : struct
{
    public override string ToString()
    {
      if (!this.hasValue)
        return "";
      return this.value.ToString();
    }
}

Что MSDN говорит:

Метод Nullable.ToString

Возвращает текстовое представление значения текущего объекта Nullable, если свойство HasValue имеет значение true, или пустую строку (""), если свойство HasValue имеет значение false.

Таким образом, следующий код выведет пустую строку в консоль, а не ArgumentNullException исключение ArgumentNullException.

static void Main(string[] args)
{
    int? a = null;
    Console.WriteLine(a.ToString()); // Prints empty string to console.
}