2013-07-21 2 views
13

Я только что прочитал SO post, в котором объясняется, что тип возврата FirstOrDefault() будет меняться в зависимости от значения выбранного элемента.FirstOrDefault Поведение с Int и Int?

Пример:

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

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

В этом примере a будет равен 0, так как значение по умолчанию равно int 0.

Тем не менее, можно добавить .Cast<int?>() в соответствии с уже связанного поста, с тем, чтобы получите null, когда запрос возвращает 0 результатов.

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

Почему я не получаю ошибку во время компиляции (или, по крайней мере, предупреждение), когда для моего первого примера, я использую Nullable Int (int?), а не обычный int?

Если я правильно понимаю, с помощью int? при выполнении моего первого запроса будет никогда результата в значении null.

+2

Ваш вопрос непонятен, мне. Какой именно код компилируется без предупреждения, где вы ожидали ошибки/предупреждения? Правильно, что значение defalt для 'int' равно' 0', а значение 'int?' - 'null'. –

+0

Hi @JeppeStigNielsen - я был смущен, почему компилятор для примера «int?» Выше дал бы мне использовать тип Nullable, даже если «null» никогда не будет возвращен. 'dasblinkenlight' полностью ответил на мой вопрос. –

ответ

9

Почему я не получаю ошибку во время компиляции (или, по крайней мере, предупреждение), когда для моего первого примера, я использую Nullable int вместо обычного int тогда? Если я правильно понял, используя int? при выполнении моего первого запроса никогда не приведет к значению null.

Ваше понимание неверное. Однако компилятор не мешает вашему объявлению переменной a как обнуляемой, поскольку это «расширяющееся» преобразование: даже если назначение из запроса LINQ никогда не вернет null, вы можете использовать другое значение для одной и той же переменной вниз ниже:

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

[в сторону] Не могли бы вы возражать против использования переменной 'a' в нескольких точках, поскольку, как я помню из Code Complete и опыта, увеличение диапазона переменной может ухудшить читаемость. –

+3

@Kevin Я бы стал первым, кто возражал против повторного использования переменной, если только не повторить ее для близкой цели. Однако компиляторы не должны нести ответственность за соблюдение лучших практик: они должны повиноваться тем, что программисты говорят им делать, позволяя программистам беспокоиться о таких «несущественных» вещах, как читаемость их собственных программ. – dasblinkenlight

+0

Спасибо за вдумчивые слова. –

Смежные вопросы