Was ist der Zweck eines Fragezeichens nach einem Typ (zum Beispiel: int? MyVariable)?

432

Typischerweise wird das Fragezeichen hauptsächlich für die Bedingung verwendet x ? "yes" : "no".

Aber ich habe eine andere Verwendung dafür gesehen, kann aber ?zum Beispiel keine Erklärung für diese Verwendung des Operators finden.

public int? myProperty
{
   get;
   set;
}
GenEric35
quelle

Antworten:

435

Dies bedeutet, dass der betreffende Werttyp ein nullbarer Typ ist

Nullable-Typen sind Instanzen der System.Nullable-Struktur. Ein nullbarer Typ kann den korrekten Wertebereich für den zugrunde liegenden Wertetyp sowie einen zusätzlichen Nullwert darstellen. Beispielsweise kann einem Nullable<Int32>ausgesprochenen "Nullable of Int32" ein beliebiger Wert von -2147483648 bis 2147483647 zugewiesen werden, oder es kann der Nullwert zugewiesen werden. A Nullable<bool>können die Werte true, false oder null zugewiesen werden. Die Möglichkeit, numerischen und booleschen Typen Null zuzuweisen, ist besonders nützlich, wenn Sie mit Datenbanken und anderen Datentypen arbeiten, die Elemente enthalten, denen möglicherweise kein Wert zugewiesen wurde. Beispielsweise kann ein boolesches Feld in einer Datenbank die Werte true oder false speichern oder undefiniert sein.

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
quelle
3
Wird für struct verwendet. Denken Sie nicht, dass es für den Unterricht wirklich nützlich ist.
MonsieurDart
8
@ MonsieurDart - deshalb lautet die Antwort "Werttyp"
Sean
3
@AntoineDahan - Wertetypen haben keine nullbaren Typen, da sie per Definition nicht nullbar sind. Ich denke, Sie denken an Java, wo es zum Beispiel einen intTyp und eine entsprechende IntegerKlasse gibt.
Sean
2
Neuere (2015) Dokumentation für nullbaren Typ hier
Dinosaurier
2
Beachten Sie auch, dass Fragezeichen einem Objekt (Instanz eines Typs) in c # 6 (VS 2015) folgen können
Zim
118

Es ist eine Abkürzung für Nullable<int>. Nullable<T>wird verwendet, um das Setzen eines Werttyps zu ermöglichen null. Werttypen können normalerweise nicht null sein .

Klaus Byskov Pedersen
quelle
3
plus eins für die Verwendung des Begriffs Kurzschrift, Ziemlich einfach!
Hari
3
Der zweite Satz verwirrt mich. Was meinst du mit "kann nicht"? Auf Compilerebene oder im Anwendungskontext.
Problemoffizier
5
@problemofficer per Definition, value typeskann nicht null sein. Wenn Sie ein int oder ein bool (die Werttypen sind) deklarieren, ohne einen bestimmten Wert zuzuweisen, haben sie weiterhin Werte (0 bzw. false), d. H. Sie wären nicht null. Nicht zugewiesen reference types, wie z. B. Objekt oder MyClass, ist dagegen null. Vielleicht möchten Sie sich über den Unterschied zwischen Werttypen und Referenztypen informieren.
Klaus Byskov Pedersen
Vielen Dank für die Erklärung. Ich verstehe jetzt.
Problemoffizier
62

Im

x ? "yes" : "no"

das ? erklärt einen if- Satz. Hier: x repräsentiert die boolesche Bedingung; Der Teil vor dem : ist der Dann- Satz und der Teil danach ist der Sonst- Satz.

In zum Beispiel

int?

das ? deklariert einen nullbaren Typ und bedeutet, dass der Typ davor einen Nullwert haben kann.

eKek0
quelle
9
Ich sehe keine Beziehung zwischen dem '?' Deklarieren eines nullfähigen Typs und eines ternären Ausdrucks. Stimmen Sie Ihre Antwort ab, Sir.
Gus Crawford
36
Ich bin mit dem obigen Kommentar von Gus nicht einverstanden. Die Frage zeigt, dass es eine mögliche Verwechslung mit dem ternären Ausdruck gibt. Diese Antwort behebt dieses Problem.
Mario Levesque
Wo würden Sie diese Art des Nullvergleichs verwenden? Innerhalb einer Rückgabe scheint es nicht erlaubt zu sein. return value ? value : "isNull";sagt mir, dass string valuenicht in bool konvertierbar ist.
C4d
Ich muss sagen, dass dies eine sehr verschlungene Antwort ist, besonders im Vergleich zu anderen auf dieser Frage. -1
FastTrack
Dies sollte die akzeptierte Antwort sein. Da ist es klar und präzise. +1
JP Dolocanog
49

Nullable Typen

Nullable-Typen sind Instanzen der System.Nullable-Struktur. Ein nullbarer Typ kann den normalen Wertebereich für den zugrunde liegenden Wertetyp sowie einen zusätzlichen Nullwert darstellen . Beispielsweise kann einem [ Nullable<Int32>], ausgesprochen "Nullable of Int32", ein beliebiger Wert von -2147483648 bis 2147483647 zugewiesen werden, oder es kann der Nullwert zugewiesen werden. Einem [ Nullable<bool>] können die Werte true oder false oder null zugewiesen werden. Die Möglichkeit, numerischen und booleschen Typen Null zuzuweisen, ist besonders nützlich, wenn Sie mit Datenbanken und anderen Datentypen arbeiten, die Elemente enthalten, denen möglicherweise kein Wert zugewiesen wurde. Beispielsweise kann ein boolesches Feld in einer Datenbank die Werte true oder false speichern oder undefiniert sein.

Ahmet Kakıcı
quelle
11

es erklärt, dass der Typ nullbar ist.

Thanos Papathanasiou
quelle
2
Ihr erster Eintrag macht angesichts der Stichprobe der Fragesteller keinen Sinn.
Binary Worrier
Nur neugierig auf die Bewertung, wenn alle ausführlichen Antworten oben :)
Naga
6

praktische Anwendung:

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

  return someFunctionThatHandlesIntAndReturnsString(value);
}
AJBauer
quelle
1
Während das OP 5 Jahre nach der Beantwortung der Frage noch aktiv ist, ist die Antwort möglicherweise nicht mehr relevant.
Erdbeere
10
für mich war es vor 3 Stunden :-)
AJBauer
3

Um die obigen Antworten zu ergänzen, finden Sie hier ein Codebeispiel

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

Dies würde einen Kompilierungsfehler ergeben:

Fehler 12 Null kann nicht in 'Test' konvertiert werden, da es sich um einen nicht nullbaren Wertetyp handelt

Beachten Sie, dass für NullableTest kein Kompilierungsfehler vorliegt. (Beachten Sie das? in der Erklärung von t2)

Sunil Purushothaman
quelle
2

int?ist eine Abkürzung für Nullable<int>. Die beiden Formen sind austauschbar.

Nullable<T>ist ein Operator, den Sie mit einem Werttyp verwenden können T, um ihn zu akzeptieren null.

Falls Sie noch nicht wissen: Werttypen sind Typen , die Werte als akzeptiert int, bool, charetc ...

Sie können keine Verweise auf Werte akzeptieren: Sie würden einen Fehler bei der Kompilierung erzeugen, wenn Sie ihnen a zuweisen null, im Gegensatz zu Referenztypen , die dies offensichtlich akzeptieren können.

Warum brauchst du das? Denn manchmal können Ihre Werttypvariablen Nullreferenzen erhalten, die von etwas zurückgegeben werden, das nicht sehr gut funktioniert, wie z. B. einer fehlenden oder undefinierten Variablen, die von einer Datenbank zurückgegeben wird.

Ich empfehle Ihnen, die Microsoft-Dokumentation zu lesen, da sie das Thema recht gut abdeckt.

Nicola Amadio
quelle