Поведение FirstOrDefault с Int и Int?

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

Пример:

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.

Ответ 1

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

Ваше понимание верное. Однако компилятор не мешает вашему объявлению переменной a как nullable, потому что это "расширяющееся" преобразование: даже если назначение из запроса 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
...