2010-08-17 14 views
13

Dlaczego otrzymuję to ostrzeżenie w języku C# z Visual Studio 2010?C# Instrukcja if skrót operatora (? :) kończy się nieosiągalnym kodem

"Unreachable expression code detected" 

z następującego kodu (DateTime.Now podkreślone na zielono falowane):

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

OK, ponieważ 'DateTime' jest strukturą i nigdy nie może mieć wartości' null'. Więc jaką wartość, aby sprawdzić w moim 'ViewState' jest pusty? – JohnB

+0

'Nieosiągalne wyrażenie' brzmi dość blisko 'Zawsze ocenia na (TRUE | FALSE)' ... czy na pewno 'dt' może mieć wartość' null'? Czy klasyczne 'if {} else {}' działa dobrze? –

+0

Literówki: więc jakiej wartości powinienem sprawdzić na wypadek, gdyby moje "ViewState" było puste? – JohnB

Odpowiedz

38

Ponieważ struct DateTime nigdy nie może być null.

Jeśli spodziewasz się wartości pustej, musisz użyć zerowalnej struktury DateTime. Można również użyć operatora null koalescencyjny zamiast operatora warunkowego, a także:

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

Albo można zrobić to jako jedną wkładką (jak w the comments):

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

Co się stanie, jeśli klawisz "StartDate" nie istnieje? – Blam

+5

@Blam: W ASP.NET, jeśli klucz ViewState nie istnieje, otrzymasz 'null'. Często wyrażam to samo, co @ Justin z jedną linią: 'return (DateTime) (ViewState [" StartDate "]? DateTime.Now);'. Działa jak marzenie. – kbrimington

+0

@Blam: Właśnie o to pytałem! @ Justin: świetne rozwiązanie, dzięki! – JohnB

3

które mogłyby być ponieważ DateTime jest struct (typ wartości) & nie jest typem odniesienia.
Dlatego porównanie go z wartością null zawsze będzie fałszywe.

4

DateTime jest typ wartości, więc to nie może być puste. W związku z tym test dla == null jest równy stałej w czasie kompilacji, więc połowa wartości?: Nigdy nie zostanie osiągnięta w czasie wykonywania.

1

Wartość DateTime nie jest pusta, więc jej wartość nigdy nie będzie miała wartości NULL.

4

Podane już odpowiedzi - że nie-nullowany typ wartości nigdy nie będzie miał wartości null, a zatem znane jest, że porównanie zwraca falsyfikat w czasie kompilacji - czy sądzisz, że zastanawiasz się nad oczywistym dalszym pytaniem? : dlaczego jest to nawet legalne? Pytanie to było wielokrotnie zadawane na SO; krótka wersja jest taka, że ​​C# zapewnia "podniesiony" operator równości dla każdej struktury, która zapewnia operator równości na typie nie podlegającym zerowaniu (jeśli zniesiony już nie istnieje).

To znaczy, ponieważ DateTime zapewnia operatorowi ==, kompilator automatycznie generuje operator == na DateTime ?, a , że operator ma zastosowanie w twoim przypadku.

+0

Kolejne często zadawane pytanie. Dlaczego kompilator zapomina wydać drugie ostrzeżenie, _ Wynik wyrażenia jest zawsze "fałszywy", ponieważ wartość typu "System.DateTime" nigdy nie jest równa "null" typu "System.DateTime?" _. To ostrzeżenie działa (przynajmniej większość typu) podniesionych wbudowanych operatorów równości '==', jak w '42 == null', ale nie zadziała dla operatorów zdefiniowanych przez użytkownika' == 'jak ten na" DateTime', kiedy są podnoszone. –

+1

@JeppeStigNielsen: Brakujące ostrzeżenie było błędem; Podejrzewam, że wprowadziłem go w C# 3. Kiedy byłem w Microsoft, nigdy nie było wystarczająco wysokim priorytetem, aby w pełni go zbadać; Nie wiem, czy został naprawiony w Roslyn, czy nie. Żałuję błędu. –

Powiązane problemy