Какова цель знака вопроса после типа (например: int? MyVariable)?

372

Обычно основное использование вопросительного знака - условное, x ? "yes" : "no".

Но я видел другое использование для него, но не могу найти объяснения этого использования оператора ?, например.

public int? myProperty
{
   get;
   set;
}
Теги:
types

9 ответов

378
Лучший ответ

Это означает, что рассматриваемый тип значения является обнуляемым типом.

Обнуляемые типы являются экземплярами структуры System.Nullable. Обнуляемый тип может представлять правильный диапазон значений для его базового типа значения, а также дополнительное нулевое значение. Например, Nullable<Int32>, произносится как "Nullable of Int32", может быть присвоено любое значение от -2147483648 до 2147483647, или ему может быть присвоено нулевое значение. Nullable<bool> можно присвоить значения true, false или null. Возможность присваивать значение null числовому и логическому типам особенно полезна, когда вы имеете дело с базами данных и другими типами данных, которые содержат элементы, которым может не быть присвоено значение. Например, логическое поле в базе данных может хранить значения true или false, или оно может быть неопределенным.

class NullableExample
{
  static void Main()
  {
      int? num = null;

      // Is the HasValue property true?
      if (num.HasValue)
      {
          System.Console.WriteLine("num = " + num.Value);
      }
      else
      {
          System.Console.WriteLine("num = Null");
      }

      // y is set to zero
      int y = num.GetValueOrDefault();

      // num.Value throws an InvalidOperationException if num.HasValue is false
      try
      {
          y = num.Value;
      }
      catch (System.InvalidOperationException e)
      {
          System.Console.WriteLine(e.Message);
      }
  }
}
  • 3
    Используется для структуры. Не думайте, что это действительно полезно для занятий.
  • 8
    @MonsieurDart - вот почему ответ говорит: «тип значения»
Показать ещё 6 комментариев
107

Это сокращение для Nullable<int>. Nullable<T> используется со значениями типов, которые не могут быть нулевыми.

  • 3
    плюс один за использование термина стенография, довольно прямо!
  • 2
    Второе предложение смущает меня. Что вы подразумеваете под "не может"? На уровне компилятора или в контексте приложения.
Показать ещё 2 комментария
57

В

x ? "yes" : "no"

? объявляет предложение if. Здесь: x представляет собой логическое условие; Часть перед : является предложением then, а часть после - предложением else.

В, например,

int?

? объявляет тип с нулевым значением и означает, что тип до него может иметь нулевое значение.

  • 9
    Я не вижу никакой связи между '?' объявление нулевого типа и троичного выражения. Голосую за ваш ответ, сэр.
  • 30
    Я не согласен с комментарием выше от Гаса. Вопрос показывает, что возможна путаница с троичным выражением. Этот ответ решает эту проблему.
Показать ещё 3 комментария
45

Обнуляемые типы

Обнуляемые типы являются экземплярами структуры System.Nullable. Обнуляемый тип может представлять нормальный диапазон значений для его базового типа значения, а также дополнительное нулевое значение. Например, [ Nullable<Int32> ], произносится как "Nullable of Int32", может быть присвоено любое значение от -2147483648 до 2147483647, или ему может быть присвоено нулевое значение. [ Nullable<bool> ] могут быть назначены значения true или false, или null. Возможность присваивать значение null числовому и логическому типам особенно полезна при работе с базами данных и другими типами данных, содержащими элементы, которым может не быть присвоено значение. Например, логическое поле в базе данных может хранить значения true или false, или оно может быть неопределенным.

11

он объявляет, что тип является нулевым.

  • 2
    Ваша первая запись не имеет смысла, учитывая образец вопросов.
6

практическое использование:

public string someFunctionThatMayBeCalledWithNullAndReturnsString(int? value)
{
  if (value == null)
  {
    return "bad value";
  }

  return someFunctionThatHandlesIntAndReturnsString(value);
}
  • 1
    Несмотря на то, что ФП все еще активен, через 5 лет после того, как вопрос был задан, ответ, возможно, уже не актуален.
  • 9
    для меня это было 3 часа назад :-)
3

Чтобы добавить к ответам выше, вот пример кода

struct Test
{
    int something;
}
struct NullableTest
{
    int something;
}
class Example
{
    public void Demo()
    {
        Test t = new Test();
        t = null;

        NullableTest? t2 = new NullableTest();
        t2 = null;
    }
}

Это даст ошибку компиляции:

Ошибка 12 Невозможно преобразовать значение null в 'Test', потому что оно не является нулевым тип значения

Обратите внимание, что для NullableTest отсутствует ошибка компиляции. (обратите внимание на? в объявлении t2)

1

int? это сокращение для Nullable<int>, две формы взаимозаменяемы.

Nullable<T> - это оператор, который можно использовать с типом значения T чтобы он принимал значение null.

Если вы этого не знаете: типы значений - это типы, которые принимают значения как int, bool, char т.д.

Они не могут принимать ссылки на значения: они генерируют ошибку во время компиляции, если вы присваиваете им null, в отличие от ссылочных типов, которые, очевидно, могут принять это.

Зачем вам это нужно? Потому что иногда ваши переменные типа значения могут получать нулевые ссылки, возвращаемые чем-то, что работает не очень хорошо, например отсутствующей или неопределенной переменной, возвращаемой из базы данных.

Я предлагаю вам прочитать документацию Microsoft, потому что она достаточно хорошо охватывает эту тему.

0

Чтобы создать необязательный параметр, добавьте ? после типа, который вы хотите обернуть. Любой тип может быть необязательным, даже ваши собственные пользовательские типы. У вас не может быть пробела между типом и ?.

var name: String? = "Bob" // Create an optional String that contains "Bob"
var peter: Person? = Person() // An optional "Person" (custom type)

// A class with a String and an optional String property
class Car {
var modelName: String // must exist
var internalName: String? // may or may not exist
}
Сообщество Overcoder
Наверх
Меню