2016-12-20 2 views
3

Когда я пытаюсь использовать? .First() для перечислимого объекта, он выдает ошибку «последовательность не содержит элементов», когда объект не содержит элементов.Почему IENumerable? .First() не работает?

Я признаю, что решение должно использовать .FirstOrDefault(), но я не понимаю, почему мое первоначальное усилие не работает. Я что-то не понимаю или это просто «одна из тех вещей»?

+0

'IEnumerable' не равно нулю, в вашем случае, только что последовательность не содержит ничего. Если ваш объект IEnumerable был нулевым, то даже «FirstOrDefault» забросил бы ошибку – Developer

ответ

9

Пустая последовательность не null, это фактический объект, в котором просто нет элементов. ?. не называет этот элемент , если выражение равно null, которого нет, поэтому вызывается First, а First выдает исключение, когда ему передается пустая последовательность.

+0

Конечно, теперь кажется очевидным, что это объясняется! Я сделал предположение о цели этого оператора, не задумываясь об этом. – paulH

4

Потому что пустая коллекция не является null.

3

Первый() явно выдает исключение, когда последовательность не содержит элементов. FirstOrDefault() дает null, если нет элементов (редактирование: вернее, оно дает значение по умолчанию, которое для ссылочных типов равно null). Что бы вы хотели, чтобы First() возвращался из пустой последовательности?

+0

«FirstOrDefault() дает null, если нет элементов» не является истинным. Он предоставит 'default (TSource)', который не обязательно «null»; это справедливо только в том случае, если «TSource» является ссылочным типом. – InBetween

+0

Да, вы правы. Это важное различие. –

5

Нулевой условный оператор (?) Проверяет значение null перед выполнением операции доступа к члену. Пустая последовательность не является нулевой, она просто не содержит элементов. Поэтому, когда вы вызываете First(), он корректно терпит неудачу, потому что нет первого элемента.

3

Согласно MSDN документации:

int? length = customers?.Length; // null if customers is null 
    Customer first = customers?[0]; // null if customers is null 
    int? count = customers?[0]?.Orders?.Count(); // null if customers, the first   customer, or Orders is null 

Поэтому, если ваша коллекция не равно нулю, то во время выполнения будет пытаться вернуть первый элемент. Поскольку коллекция пуста и вы не использовали FirstOrDefault, выдается исключение.

Ссылка: https://msdn.microsoft.com/en-us/library/dn986595.aspx

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