2013-07-21 14 views
13

Właśnie przeczytałem SO post, który wyjaśnił, że typ zwracany przez FirstOrDefault() będzie się różnić w zależności od wartości wybranego elementu.FirstOrDefault Behavior with Int i Int?

przykład:

ICollection<String> list = new List<String>(); 
list.Add("bye"); 

int a = (from x in list where (x == "hi") select x.Length).FirstOrDefault(); 

W tym przykładzie a będzie równe 0, ponieważ wartość domyślna int 0.

Jednakże można dodać .Cast<int?>() jak na już związanego stanowiskach w celu get null, gdy zapytanie zwróci 0 wyników.

int? a = (from x in list where ... x.Length).Cast<int?>().FirstOrDefault(); 

Dlaczego nie pojawia się błąd kompilacji (lub przynajmniej ostrzeżenie), gdy na moim pierwszym przykładzie mogę używać pustych int (int?) zamiast regularnej int?

Jeśli dobrze rozumiem, używając int? podczas wykonywania mój pierwszy kwerenda będzie nigdy doprowadzić do wartości null.

+2

Twoje pytanie nie jest dla mnie jasne. Jaki dokładnie kod kompiluje bez ostrzeżenia, gdzie spodziewano się błędu/ostrzeżenia? Prawdą jest, że wartość defalt dla 'int' wynosi' 0', a wartość 'int?' To 'null'. –

+0

Hi @JeppeStigNielsen - Byłem zdezorientowany, dlaczego kompilator, dla powyższego przykładu "int?", Pozwoliłby mi użyć typu Nullable, chociaż 'null' nigdy nie zostanie zwrócony. 'dasblinkenlight' w pełni odpowiedział na moje pytanie. –

Odpowiedz

9

Dlaczego nie pojawia się błąd kompilacji (lub przynajmniej ostrzeżenie), gdy na moim pierwszym przykładzie używam Nullable int zamiast regularnej int wtedy? Jeśli rozumiem poprawnie, używając int? podczas wykonywania mojej pierwszej kwerendy nigdy nie będzie mieć wartości null.

Twoje zrozumienie jest prawidłowe. Jednak kompilator nie koliduje z twoją chęcią zadeklarowania zmiennej a jako zerowalnej, ponieważ jest to konwersja "poszerzająca": nawet jeśli przypisanie z zapytania LINQ nigdy nie zwróciło wartości null, możesz mieć inne zastosowanie dla tej samej zmiennej w dół poniżej:

int? a = (from x in list where (x == "hi") select x.Length).FirstOrDefault(); 
// Do something with `a`, which will not be null 
... 
a = null; 
if (someCondition) { 
    a = someNotNullValue(); 
} 
// Here, a may or may not be null 
... 
+0

[na stronie] Czy nie argumentowałbyś przeciwko używaniu zmiennej 'a' w wielu miejscach, ponieważ, jak pamiętam z Code Complete i doświadczenia, zwiększenie zakresu zmiennej może zaszkodzić czytelności. –

+3

@Kevin Byłbym pierwszym, który argumentowałby przeciwko ponownemu użyciu zmiennej, chyba że ktoś użyje jej ponownie w ściśle powiązanym celu. Kompilatorzy jednak nie powinni być pociągnięci do odpowiedzialności za egzekwowanie najlepszych praktyk: muszą przestrzegać poleceń programistów, pozwalając programistom martwić się o takie "nieważne" rzeczy, takie jak czytelność własnych programów. – dasblinkenlight

+0

Dziękuję za przemyślane słowa. –

Powiązane problemy