Jaki jest cel znaku zapytania po typie (na przykład: int? MyVariable)?

433

Zazwyczaj głównym używanie znaku zapytania jest dla warunkowego x ? "yes" : "no".

Ale widziałem inne zastosowanie tego, ale nie mogę na przykład znaleźć wyjaśnienia tego zastosowania ?operatora.

public int? myProperty
{
   get;
   set;
}
GenEric35
źródło

Odpowiedzi:

437

Oznacza to, że typ wartości, o którym mowa, jest rodzajem zerowalnym

Typy zerowalne są instancjami struktury System.Nullable. Typ dopuszczający wartości zerowe może reprezentować prawidłowy zakres wartości dla swojego podstawowego typu wartości, a także dodatkową wartość zerową. Na przykład, Nullable<Int32>wymawianemu „Nullable Int32” można przypisać dowolną wartość od -2147483648 do 2147483647 lub można mu przypisać wartość null. Nullable<bool>Można przypisać wartości true, false lub null. Możliwość przypisania wartości null do typów numerycznych i boolowskich jest szczególnie przydatna, gdy mamy do czynienia z bazami danych i innymi typami danych, które zawierają elementy, którym nie można przypisać wartości. Na przykład pole boolowskie w bazie danych może przechowywać wartości true lub false lub może być niezdefiniowane.

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);
      }
  }
}
Sean
źródło
3
Używany do struktury. Nie sądzę, że jest to przydatne na zajęciach.
MonsieurDart,
8
@MonsieurDart - dlatego odpowiedź brzmi „typ wartości”
Sean
3
@AntoineDahan - typy wartości nie mają typów zerowalnych, ponieważ z definicji nie mają wartości zerowych. Myślę, że myślisz o Javie , na przykład o inttypie i odpowiedniej Integerklasie.
Sean
2
nowsza dokumentacja (2015) dla typu zerowalnego tutaj
dinozaur
2
Zauważ również, że znak zapytania może podążać za obiektem (instancją typu) w c # 6 (VS 2015)
Zim,
118

To jest skrót od Nullable<int>. Nullable<T>służy do ustawienia typu wartości na null. Typy wartości zwykle nie mogą mieć wartości NULL .

Klaus Byskov Pedersen
źródło
3
plus jeden za użycie terminu „stenografia”, całkiem prosto!
Hari,
3
Drugie zdanie myli mnie. Co rozumiesz przez „nie mogę”? Na poziomie kompilatora lub w kontekście aplikacji.
problemofficer
5
@problemofficer na definicję, value typesnie może być pusty. Jeśli zadeklarujesz int lub bool (które są typami wartości) bez specjalnego przypisania wartości, nadal będą miały wartości (odpowiednio 0 i fałsz), tj. nie byłyby zerowe. Nieprzypisane reference types, takie jak object lub MyClass, z drugiej strony będą zerowe. Możesz przeczytać o różnicy między typami wartości a typami referencyjnymi.
Klaus Byskov Pedersen
Dziękuję za wyjaśnienie. Teraz rozumiem.
problemofficer
62

W

x ? "yes" : "no"

? deklaruje zdanie if . Tutaj: x oznacza warunek logiczny; Część przed : to wtedy zdanie, a część po to inny wyrok.

Na przykład

int?

? deklaruje typ zerowalny i oznacza, że ​​typ przed nim może mieć wartość zerową.

eKek0
źródło
9
Nie widzę żadnego związku między „?” deklarowanie typu zerowego i wyrażenie trójskładnikowe. Głosuję swoją odpowiedź, proszę pana.
Gus Crawford,
36
Nie zgadzam się z powyższym komentarzem Gusa. Pytanie pokazuje, że istnieje możliwość pomylenia z wyrażeniem potrójnym. Ta odpowiedź rozwiązuje ten problem.
Mario Levesque,
Gdzie użyłbyś tego rodzaju porównywania zerowego? Wewnątrz zwrotu wydaje się to niedozwolone. return value ? value : "isNull";mówi mi, że string valuenie można zamienić na bool.
C4d
Muszę powiedzieć, że jest to bardzo skomplikowana odpowiedź, szczególnie w porównaniu z innymi w tym pytaniu .. -1
FastTrack
To powinna być zaakceptowana odpowiedź. Ponieważ jest to jasne i precyzyjne. +1
JP Dolocanog
49

Typy zerowalne

Typy zerowalne są instancjami struktury System.Nullable. Typ dopuszczający wartości zerowe może reprezentować normalny zakres wartości dla jego podstawowego typu wartości, a także dodatkową wartość zerową . Na przykład [ Nullable<Int32>], wymawiane jako „Nullable Int32”, można przypisać dowolną wartość od -2147483648 do 2147483647 lub można mu przypisać wartość zerową. Do [ Nullable<bool>] można przypisać wartości true lub false lub null. Możliwość przypisania wartości null do typów numerycznych i boolowskich jest szczególnie przydatna w przypadku baz danych i innych typów danych zawierających elementy, którym nie można przypisać wartości. Na przykład pole boolowskie w bazie danych może przechowywać wartości true lub false lub może być niezdefiniowane.

Ahmet Kakıcı
źródło
11

deklaruje, że typ jest zerowalny.

Thanos Papathanasiou
źródło
2
Twój pierwszy wpis nie ma sensu, biorąc pod uwagę próbkę pytającego.
Binary Worrier
Po prostu ciekawi mnie ocena, gdy wszystkie szczegółowe odpowiedzi powyżej :)
Naga
6

praktyczne zastosowanie:

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

  return someFunctionThatHandlesIntAndReturnsString(value);
}
AJBauer
źródło
1
Chociaż program operacyjny jest nadal aktywny, 5 lat po zadaniu pytania odpowiedź może nie być już aktualna.
Strawberry
10
dla mnie to było 3 godziny temu :-)
AJBauer
3

Aby dodać do powyższych odpowiedzi, oto przykładowy kod

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;
    }
}

Dałoby to błąd kompilacji:

Błąd 12 Nie można przekonwertować wartości null na „Test”, ponieważ jest to typ wartości, który nie ma wartości zerowej

Zauważ, że nie ma błędu kompilacji dla NullableTest. (zwróć uwagę na? w deklaracji t2)

Sunil Purushothaman
źródło
2

int?jest skrótem od Nullable<int>. Te dwie formy są wymienne.

Nullable<T>to operator, którego można użyć z typem wartości, Taby go zaakceptować null.

W przypadku, gdy nie wiem: wartości typy są typami, który przyjmuje wartości jak int, bool, charitp ...

Nie mogą akceptować odwołań do wartości: wygenerowaliby błąd czasu kompilacji, jeśli przypiszesz im a null, w przeciwieństwie do typów referencji , które oczywiście mogą to zaakceptować.

Dlaczego miałbyś tego potrzebować? Ponieważ czasami zmienne typu wartości mogą otrzymywać referencje zerowe zwracane przez coś, co nie działało zbyt dobrze, na przykład brakującą lub niezdefiniowaną zmienną zwróconą z bazy danych.

Sugeruję przeczytanie Dokumentacji Microsoft, ponieważ dość dobrze obejmuje ona ten temat.

Nicola Amadio
źródło