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

433

Как правило , основное назначение знака вопроса для условного, x ? "yes" : "no".

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

public int? myProperty
{
   get;
   set;
}
GenEric35
источник

Ответы:

438

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

Обнуляемые типы являются экземплярами структуры System.Nullable. Обнуляемый тип может представлять правильный диапазон значений для его базового типа значения, а также дополнительное нулевое значение. Например, Nullable<Int32>объявленному «Nullable of Int32» может быть присвоено любое значение от -2147483648 до 2147483647, или ему может быть присвоено нулевое значение. A 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
Используется для структуры. Не думайте, что это действительно полезно для занятий.
MonsieurDart
8
@MonsieurDart - вот почему ответ говорит: «тип значения»
Шон
3
@AntoineDahan - типы значений не имеют обнуляемых типов, так как по определению не обнуляются. Я думаю, что вы думаете о Java, где есть intтип и соответствующий Integerкласс, например.
Шон
2
более свежая (2015 г.) документация для обнуляемого типа здесь
динозавр
2
Также обратите внимание, что знак вопроса может следовать за объектом (экземпляром типа) в c # 6 (VS 2015)
Zim
119

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

Клаус Бысков Педерсен
источник
3
плюс один за использование термина стенография, довольно прямо!
Хари
3
Второе предложение смущает меня. Что вы подразумеваете под "не может"? На уровне компилятора или в контексте приложения.
problemofficer
5
@problemofficer для определения, value typesне может быть нулевым. Если вы объявляете int или bool (которые являются типами значений) без специального присваивания значения, они все равно будут иметь значения (0 и false соответственно), т.е. они не будут нулевыми. Неназначенные reference types, такие как object или MyClass, будут, с другой стороны, равны нулю. Вы можете прочитать разницу между типами значений и ссылочными типами.
Клаус Бысков Педерсен
Спасибо за объяснение. Теперь я понимаю.
problemofficer
62

В

x ? "yes" : "no"

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

Например, в

int?

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

eKek0
источник
9
Я не вижу никакой связи между '?' объявляющий нулевой тип и троичное выражение. Голосую за ваш ответ, сэр.
Гас Кроуфорд
36
Я не согласен с комментарием выше от Гаса. Вопрос показывает, что возможна путаница с троичным выражением. Этот ответ решает эту проблему.
Марио Левеск
Где бы вы использовали этот вид нулевого сравнения? Внутри возврата это, похоже, недопустимо. return value ? value : "isNull";говорит мне, что string valueне конвертируется в bool.
C4d
Я должен сказать, что это очень запутанный ответ, особенно по сравнению с другими по этому вопросу .. -1
FastTrack
Это должен быть принятый ответ. Так как это ясно и точно. +1
JP Dolocanog
49

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

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

Ахмет Какичи
источник
11

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

Танос Папатанасиу
источник
2
Ваша первая запись не имеет смысла, учитывая образец вопросов.
Двоичный беспорядок
Просто интересно узнать рейтинг, когда все подробно ответят выше :)
Naga
6

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

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

  return someFunctionThatHandlesIntAndReturnsString(value);
}
AJBauer
источник
1
Несмотря на то, что ФП все еще активен, через 5 лет после того, как вопрос был задан, ответ, возможно, уже не актуален.
Клубника
10
для меня это было 3 часа назад :-)
AJBauer
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

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

Сунил Пурушотаман
источник
2

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

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

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

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

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

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

Никола Амадио
источник