Jaka jest domyślna wartość typu dopuszczającego wartość null „int?” (w tym znak zapytania)?

102

Jaka jest domyślna wartość zmiennej wystąpienia klasy w języku C # int??

Na przykład w poniższym kodzie jaka będzie wartość, MyNullableIntjeśli nigdy nie zostanie jawnie przypisana?

class MyClass
{
    public int? MyNullableInt;
}

(Wydaje się prawdopodobne, że odpowiedź prawie na pewno brzmi albo nullalbo 0, ale która z nich to jest?)

Jon Schneider
źródło
9
Dlaczego głos przeciw? (Odpowiedź na to pytanie nie była początkowo dla mnie oczywista bez faktycznego uruchomienia kodu w celu przetestowania zachowania; i, co zaskakujące, nie mogłem znaleźć duplikatu tego pytania w StackOverflow ani łatwo znaleźć go w innym miejscu za pośrednictwem Google.)
Jon Schneider
1
Mogłeś tu zajrzeć - pierwsze trafienie google dla mnie.
500 - Wewnętrzny błąd serwera
2
@ 500 - Znalazłem ten artykuł, gdy szukałem - faktycznie połączyłem się z nim w mojej własnej odpowiedzi poniżej - ale o ile wiem, artykuł nie stwierdza wyraźnie, że domyślna wartość instancji typu dopuszczającego wartość null jest null. Mówi się , że „Wartość domyślna HasValue to false. Właściwość Value nie ma wartości domyślnej”, ale to nie odpowiada bezpośrednio na moje pierwotne pytanie bez dodatkowego kopania.
Jon Schneider,
2
Zastanawiam się, czy to dlatego, że mogłeś po prostu ustawić punkt przerwania i zobaczyć, jaka jest wartość, czy w typie Immediate Window int? x;i zobaczyć, jaki jest wynik?
Rufus L

Odpowiedzi:

136

Wartość domyślna dla int?- i dla każdego typu dopuszczającego wartość null, który używa znaku „type?” deklaracja - jest null.

Dlaczego tak się dzieje:

  • int?jest cukrem syntaktycznym dla typu Nullable <T> (gdzie T jest int), strukturą. ( odniesienie )
  • Nullable<T>Typ ma hasValue bool człon, który podczas falsesprawia, że Nullable<T>instancja „akt jak” nullwartości. W szczególności metoda Nullable <T> .Equals jest zastępowana w celu zwrócenia, truegdy Nullable<T>with HasValue == falsejest porównywana z nullwartością rzeczywistą .
  • W specyfikacji języka C # 11.3.4 początkową wartością domyślną wystąpienia struktury są wszystkie pola typu wartości tej struktury ustawione na wartość domyślną, a wszystkie pola typu odwołania tej struktury są ustawione na null.
  • Wartość domyślna boolzmiennej w C # to false ( odwołanie ). Dlatego HasValuewłaściwość Nullable<T>wystąpienia domyślnego to false; co z kolei sprawia, że Nullable<T>sama instancja zachowuje się jak null.
Jon Schneider
źródło
Kiedy zmieniam deklarację z int? x = null;na int? x;, otrzymuję błędy kompilatora w dalszej części kodu: „Użycie nieprzypisanej zmiennej lokalnej x”.
John Pick
1
@JohnPick To funkcja kompilatora C # mająca na celu zapobieganie błędom, które mogą wyniknąć z „zapomnienia” o zainicjowaniu zmiennej przed jej użyciem. Sytuacja, w której może wystąpić niezainicjowanej int? kiedy jest zmienną składową klasy. Przykłady obu tutaj: blogs.msdn.microsoft.com/abhinaba/2005/11/08/…
Jon Schneider
Więc w zasadzie to miejsce jest twoim blogiem technicznym? Zadajesz pytania, na które wystarczy uruchomić kod, aby uzyskać odpowiedź, a następnie sam odpowiadasz na to pytanie w ciągu tej samej minuty.
GôTô
4
@JonSchneider w porządku, moja wina
GôTô
VS jest kompilator wskazówkę / ostrzeżenie jest mylące: Field 'id' is never assigned to, and will always have its default value 0. Dziwne, prawda?
Hendy Irawan
32

Czułem, że ważne jest udostępnienie Nullable<T>.GetValueOrDefault()metody, która jest szczególnie przydatna podczas pracy z obliczeniami matematycznymi wykorzystującymi wartości Nullable<int>aka int?. Wiele razy nie musisz sprawdzać HasValuewłaściwości i możesz po prostu użyć GetValueOrDefault()zamiast tego.

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());

Linia poleceń pokazująca powyższy kod działający

Brian Ogden
źródło
0
var x = default (int?);
Console.WriteLine("x == {0}", (x == null) ? "null" : x.ToString());
Rufus L.
źródło