W opisie wyjątku występuje paradoks: Obiekt dopuszczający wartości zerowe musi mieć wartość (?!)
To jest problem:
Mam DateTimeExtended
klasę
{
DateTime? MyDataTime;
int? otherdata;
}
i konstruktor
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime.Value;
this.otherdata = myNewDT.otherdata;
}
uruchomienie tego kodu
DateTimeExtended res = new DateTimeExtended(oldDTE);
rzuca InvalidOperationException
z komunikatem:
Obiekt zerowalny musi mieć wartość.
myNewDT.MyDateTime.Value
- jest ważny i zawiera zwykły DateTime
obiekt.
Jakie jest znaczenie tego przesłania i co robię źle?
Zauważ, że oldDTE
nie jest null
. Usunąłem Value
z, myNewDT.MyDateTime
ale ten sam wyjątek został zgłoszony z powodu wygenerowanego setera.
Odpowiedzi:
Powinieneś zmienić linię
this.MyDateTime = myNewDT.MyDateTime.Value;
na justthis.MyDateTime = myNewDT.MyDateTime;
Wyjątek, który otrzymałeś, został zgłoszony we
.Value
właściwości NullableDateTime
, ponieważ jest on wymagany do zwróceniaDateTime
(ponieważ taka jest umowa dla.Value
stanów), ale nie może tego zrobić, ponieważ nie maDateTime
zwrotu, więc zgłasza wyjątek.Ogólnie rzecz biorąc, złym pomysłem jest ślepe wywoływanie
.Value
typu zerowalnego, chyba że masz wcześniejszą wiedzę, że ta zmienna MUSI zawierać wartość (np. Poprzez.HasValue
sprawdzenie).EDYTOWAĆ
Oto kod
DateTimeExtended
, który nie zgłasza wyjątku:Testowałem to w ten sposób:
Dodanie
.Value
ONother.MyDateTime
spowoduje wyjątek. Usunięcie go pozbywa się wyjątku. Myślę, że szukasz w złym miejscu.źródło
.Value
obiekt zerowy ma sens (tak mi się wydaje), ale komunikat wyjątku jest bardzo mylący, jeśli masz do czynienia z dwoma obiektami zerowalnymi. Coś w rodzaju „Właściwość .Value wymaga, aby obiekt nie był zerowy”, miałoby o wiele więcej sensu.Przy użyciu metody rozszerzenie LINQ (np
Select
,Where
), funkcja lambda może być konwertowane do SQL, które nie mogą zachowywać się identycznie do kodu C #. Na przykład, zwarcie C # jest oceniane&&
i||
są konwertowane na chętnyAND
i SQLOR
. Może to powodować problemy podczas sprawdzania wartości zerowej w lambda.Przykład:
źródło
Spróbuj upuścić
.value
źródło
W tym przypadku oldDTE ma wartość NULL, więc przy próbie uzyskania dostępu do oldDTE.Value zgłaszany jest wyjątek InvalidOperationException, ponieważ nie ma żadnej wartości. W twoim przykładzie możesz po prostu zrobić:
źródło
Przypisuj członków bezpośrednio bez
.Value
części:źródło
Wygląda na to, że oldDTE.MyDateTime ma wartość NULL, więc konstruktor próbował przyjąć jego wartość - która wyrzuciła.
źródło
Otrzymałem ten komunikat podczas próby uzyskania dostępu do wartości obiektu o wartości zerowej.
spowoduje to błąd. Najpierw sprawdź, czy obiekt nie jest pusty
To działa.
źródło
this.MyDateTime = myNewDT.MyDateTime.Value;
niesName = myObj.Name;
Mam to rozwiązanie i działa dla mnie
źródło