Яке значення за замовчуванням для нульового типу "int?" (включаючи знак питання)?


100

У C #, яке значення за замовчуванням має змінну типу екземпляра класу int??

Наприклад, у наведеному нижче коді яке значення матиме MyNullableInt, якщо воно ніколи не буде призначено прямо?

class MyClass
{
    public int? MyNullableInt;
}

(Мабуть, ймовірно, що відповідь майже напевно є nullабо 0, але яка з них?)


9
Чому потік? (Відповідь на це запитання для мене спочатку не була очевидною без фактичного запуску коду для перевірки поведінки; і дивно, я не зміг знайти дублікат цього питання в StackOverflow або легко допрацьований в іншому місці через Google.)
Джон Шнайдер

1
Ви могли заглянути сюди - перший для мене хіт Google.
500 - Внутрішня помилка сервера

2
@ 500 - Я знайшов цю статтю, коли я досліджував - я насправді пов’язаний з нею у своїй власній відповіді нижче - але, наскільки я можу сказати, у статті прямо не вказано, що значення за замовчуванням для екземпляра типу, що міняється, за замовчуванням є нульовим. Це дійсно сказати , «Значення за замовчуванням для HasValue помилкова. Значення властивості не має значення по замовчуванням», але це не відразу відповів на мій оригінальний питання , без якого - або додаткового копання.
Джон Шнайдер

2
Цікаво, чи це було тому, що ви могли просто встановити точку перерви і побачити, що таке значення, або у типі «Негайне вікно» int? x;і побачити, що це результат?
Руфус Л

Відповіді:


135

Значення за замовчуванням для int?- і для будь-якого зведеного типу, який використовує "тип?" декларація - є null.

Чому це так:

  • int?є синтаксичним цукром для типу Nullable <T> (де T є int), структура. ( довідник )
  • Nullable<T>Тип має HasValue Його елемент, який , коли false, робить Nullable<T>екземпляр «діяти як» в nullзначення. Зокрема, Nullable <T> метод .equals переопределяется для повернення , trueколи Nullable<T>з HasValue == falseпорівнюється з фактичним nullзначенням.
  • З специфікації мови C # 11.3.4 , початкове значення за замовчуванням екземпляра структури - це всі типи значень типу структури, встановлені на їх значення за замовчуванням, і всі поля посилального типу цього структури, встановлені на null.
  • Значенням boolзмінної у C # за замовчуванням є false ( посилання ). Тому HasValueвластивість Nullable<T>екземпляра за замовчуванням є false; що, в свою чергу, змушує Nullable<T>сам цей екземпляр діяти null.

Коли я змінюю декларацію з int? x = null;на int? x;, я отримую помилки компілятора далі в коді: "Використання непризначеної локальної змінної x".
Джон Пік

1
@JohnPick Це функція компілятора C #, призначена для запобігання помилок, які можуть виникнути у вас, "забувши", ініціалізувати змінну перед її використанням. Ситуація, коли можна зіткнутися з неініціалізованим інтом? це коли це змінна частина класу. Приклади обох тут: blogs.msdn.microsoft.com/abhinaba/2005/11/08/…
Джон Шнайдер

Так що в основному це місце - ваш блог технологій? Ви ставите питання, на які вам просто потрібно запустити код, щоб отримати відповідь, а потім відповісти на запитання самостійно в цю ж хвилину.
GôTô

4
@JonSchneider досить справедливо, моє погано тоді
GôTô

VS в компілятор натяк / попередження в оману: Field 'id' is never assigned to, and will always have its default value 0. Дивно, чи не так?
Хенді Іраван

30

Мені було важливо поділитися Nullable<T>.GetValueOrDefault()методом, який особливо зручний при роботі з математичними обчисленнями, які використовують значення Nullable<int>aka int?. Існує багато разів, коли вам не потрібно перевіряти HasValueмайно, і ви можете просто використовувати GetValueOrDefault()замість цього.

var defaultValueOfNullableInt = default(int?);
Console.WriteLine("defaultValueOfNullableInt == {0}", (defaultValueOfNullableInt == null) ? "null" : defaultValueOfNullableInt.ToString());

var defaultValueOfInt = default(int);
Console.WriteLine("defaultValueOfInt == {0}", defaultValueOfInt);

Console.WriteLine("defaultValueOfNullableInt.GetValueOrDefault == {0}", defaultValueOfNullableInt.GetValueOrDefault());

Командний рядок, що показує код, що працює вище


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.