Ihre MSDN Zitat Echos §4.1.10 der C# 5.0-Spezifikation:
Ein Nullable Type T?
geschrieben wird, Dabei ist T
der zugrunde liegende Typ. Diese Syntax wird für System.Nullable<T>
Kurzschrift, und die beiden Formen können austauschbar verwendet werden.
Aber "austauschbar" ist eine übermäßige Vereinfachung. Es stimmt, dass T?
bedeutet System.Nullable<T>
, aber wie Sie entdeckt haben, können Sie T?
nicht überall verwenden, dass Sie System.Nullable<T>
verwenden können. Insbesondere die Art von Mitglied-Zugang (§7.6.4) in Ihrem Beispiel erfordert einen einfach Namen (§7.6.2):
[§7.6] Primäre Ausdrücke, die einfachstenen Formen schließen von Ausdrücken.
primär expression:
Primär-no-Array-Erstellungs Ausdruck
Array-creation-expression
Primär-no-Array-Erstellungs Ausdruck
wörtliche
einfach Name
klammerten-expression
Mitglied-Zugang
...
[§7.6.2] Ein einfacher -name entweder die Form oder die I
Form I<A1, ..., AK>
, wo I
ist ein einzelner Identifikator und <A1, ..., AK>
ist eine optionale Typargumentliste.
[§7.6.4] A Mitglied-access entweder die Form oder die E.I
Form E.I<A1, ..., AK>
, wo E
ist ein Primärausdruck, I
eine einzige Kennung und <A1, ..., AK>
ist ein optionaler Typ -argument-list.
Nullable<T>
ist ein einfach Name und T?
ist nicht, so die ehemalige compiles während letztere nicht.
Warum benötigen die Sprache C# Designer einen Memberzugriff Ausdruck einen einfach Namen zu verwenden, wie einen Typen dagegen? Ich nehme an, nur sie können es mit Sicherheit sagen, aber vielleicht hat diese Anforderung die Grammatik vereinfacht: In einem Ausdruck kann der Compiler annehmen, dass ?
immer der bedingte (ternäre) Operator ist und möglicherweise kein NULL-fähiger Typspezifizierer.
Im Nachhinein war dies jedoch eine glückliche Wahl, die es C# 6.0 erlaubte, den Operator ?.
hinzuzufügen, ohne bestehende Programme zu unterbrechen. Betrachten wir zum Beispiel diesen pathologischen Beispiel:
struct S
{
public bool Equals(int x, int y) { return false; }
}
class C
{
public static void Main()
{
S? S = new S();
Console.WriteLine(S?.Equals(1, 1)); // "True" or "False"?
}
}
Sollte S?.Equals
als Nullable<S> . Equals
, einen Aufruf der Equals
statische Methode der Klasse Object
analysiert werden? Oder sollte es als S ?. Equals
, ein Null-bedingter Aufruf an die Equals
Instanz Methode der Variablen S
geparst werden? Weil S?
kein einfacher Name ist, ist es eindeutig Letzteres.
Es ist eine Syntax-Sache. Der Parser kann das "?." Nicht herausfinden. – jwg
Das ist eine gute Frage, obwohl ich nicht weiß, was das bedeuten würde, Was würden wir versuchen, mit Nullable .Equals (1, 2) zu testen? (Ich bin nicht gemein, ist eine echte Frage) –
hardkoded
Beginnend mit C# 6, '?.' Als Null-bedingte Prüfung verwendet, daher ist es Syntaxfehler. Bei Verwendung einer früheren Version, bei der "?." Nicht als einzelner Operator erkannt wird, ist die Situation möglicherweise anders. –