2010-08-17 2 views
13

Warum bekomme ich diese Warnung in C# mit Visual Studio 2010?C# Wenn Anweisung Kurzschriftoperatoren (? :) führt zu nicht erreichbaren Code

"Unreachable expression code detected" 

aus dem folgenden Code (DateTime.Now in grün unterstrichen verschnörkeln):

public DateTime StartDate 
{ 
    get 
    { 
    DateTime dt = (DateTime)ViewState["StartDate"]; 
    return ((dt == null) ? DateTime.Now : dt); 
    } 
} 
+4

Okay, weil 'DateTime' eine Struktur ist und niemals' null' sein kann. Also, welchen Wert, den ich in meinem 'ViewState' suche, ist leer? – JohnB

+0

'Unreachable expression' klingt ziemlich nah an' Always evaluates to (TRUE | FALSE) '... sind Sie sicher,' dt' könnte 'null' sein? Oder funktioniert das klassische 'if {} else {}' gut? –

+0

Tippfehler: Auf welchen Wert sollte ich achten, wenn mein 'ViewState' leer ist? – JohnB

Antwort

38

Da eine Datetime-Struktur nie null sein kann.

Wenn Sie einen möglichen Nullwert erwarten, müssen Sie eine Nullable-DateTime-Struktur verwenden. Sie könnten auch die Null-Koaleszenz-Operator anstelle des bedingten Operator auch:

public DateTime StartDate 
{ 
    get 
    { 
     DateTime? dt = (DateTime?)ViewState["StartDate"]; 
     return dt ?? DateTime.Now; 
    } 
} 

Oder man könnte es als Einzeiler tun (wie in the comments):

public DateTime StartDate 
{ 
    get { return (DateTime)(ViewState["StartDate"] ?? DateTime.Now); } 
} 
+1

Was passiert also, wenn der "StartDate" Schlüssel nicht existiert? – Blam

+5

@Blam: Wenn in ASP.NET der ViewState-Schlüssel nicht existiert, erhalten Sie 'null'. Ich sage oft dasselbe wie @Justin mit einem Einzeiler: 'return (DateTime) (ViewState [" StartDate "] ?? DateTime.Now);'. Klappt wunderbar. – kbrimington

+0

@Blam: Ich war gerade dabei, das selbst zu fragen! @Justin: großartige Lösung, danke! – JohnB

3

das sein könnte weil DateTime ist eine Struktur (Werttyp) & kein Referenztyp.
Daher wird der Vergleich mit Null immer falsch sein.

1

Datetime kann nicht null sein

4

Datetime ein Werttyp ist, so dass es nie null sein kann. Daher wird der Test für == null zur Kompilierzeit als Konstante false ausgewertet, so dass die Hälfte von:: zur Laufzeit nie erreicht wird.

1

DateTime ist nicht nullfähig, daher wird der Wert nie null sein.

4

Die bereits gegebenen Antworten - dass ein nicht nullbarer Wertetyp niemals null sein wird und daher der Vergleich zur Kompilierzeit false zurückgibt - sind korrekt. Sie könnten sich über die offensichtliche Folgefrage wundern : warum ist das sogar legal? Diese Frage wurde viele Male zu SO gestellt; Die kurze Version ist, dass C# einen "aufgehobenen" Gleichheitsoperator für jede Struktur bereitstellt, die einen Gleichheitsoperator auf dem nicht nullbaren Typ bereitstellt (wenn ein aufgehobener nicht bereits existiert).

Das heißt, weil DateTime stellt einen == -Operator zur Verfügung, der Compiler generiert automatisch einen Operator == für DateTime? Und , dass Operator in Ihrem Fall anwendbar ist.

+0

Eine weitere häufig gestellte Frage. Warum vergißt der Compiler, die andere Warnung auszugeben, _Das Ergebnis des Ausdrucks ist immer 'falsch', da ein Wert vom Typ 'System.DateTime' niemals gleich 'Null' vom Typ 'System.DateTime?' _ Ist. Diese Warnung funktioniert (zumindest das meiste des Typs) von eingebauten Gleichheitsoperatoren '=', wie in '42 == null', funktioniert aber nicht für benutzerdefinierte Operatoren '== 'wie die auf' DateTime', wenn sie aufgehoben werden. –

+1

@JeppeStigNielsen: Die fehlende Warnung war ein Bug; Ich vermute, dass ich es in C# 3 eingeführt habe. Als ich bei Microsoft war, war es nie eine ausreichend hohe Priorität, um es vollständig zu untersuchen. Ich weiß nicht, ob es in Roslyn behoben wurde oder nicht. Ich bedauere den Fehler. –

Verwandte Themen