Я часто сталкиваюсь с таким кодом:
if ( items != null)
{
foreach(T item in items)
{
//...
}
}
По сути, if
условие гарантирует, что foreach
блок будет выполняться, только если items
он не равен нулю. Мне интересно, if
действительно ли это условие необходимо, или foreach
он справится с ситуацией, если items == null
.
Я имею в виду, могу я просто написать
foreach(T item in items)
{
//...
}
не беспокоясь о том items
, нулевое значение или нет? Является ли if
условие излишним? Или это зависит от типа от items
или , может быть , на T
а?
null
) , обобщающей весь цикл на ЖК - дисплееEnumerable
(как использование??
будет ), б) требовать добавления метода расширения к каждому проекту, или в) требовать исключенияnull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) в начале (cuz,null
означает N / A, тогда как пустой список означает, что он применяется, но есть в настоящее время, ну, пусто !, т. е. Empl. может иметь комиссионные, которые отсутствуют для не-продаж, или пустые для продаж, если они не заработали).Ответы:
Вам все равно нужно проверить, если (items! = Null), иначе вы получите NullReferenceException. Однако вы можете сделать что-то вроде этого:
но вы можете проверить его работоспособность. Поэтому я по-прежнему предпочитаю сначала иметь if (items! = Null).
Основываясь на предложении Эрика Липперта, я изменил код на:
источник
IEnumerable<T>
который, в свою очередь, превращается в перечислитель в интерфейс, что замедляет итерацию. Мой тест показал 5-кратную деградацию для итерации по массиву int.Используя C # 6, вы можете использовать новый условный оператор null вместе с
List<T>.ForEach(Action<T>)
(или ваш собственныйIEnumerable<T>.ForEach
метод расширения).источник
null
) обобщения всего цикла на ЖК-дисплееEnumerable
(как при использовании??
); б) требует добавления метода расширения в каждый проект; в) ) требуется избегатьnull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.), чтобы начать с (cuz,null
означает N / A, тогда как пустой список означает, что он применяется, но в настоящее время, ну, пуст !, то есть Empl. может иметь Комиссии, которые N / A для не-продаж или пусто для продаж, если они не заработали).items
этоList<T>
хотя, а не просто такIEnumerable<T>
. (Или у вас есть собственный метод расширения, о котором вы сказали, что не хотите, чтобы он был ...) Кроме того, я бы сказал, что действительно не стоит добавлять 11 комментариев, все в основном говорят, что вам нравится конкретный ответ.foreach
. В частности, для списка, который, как мне кажется, преобразуется вfor
цикл.Настоящий вывод здесь должен заключаться в том, что последовательность почти никогда не должна быть нулевой . Просто сделайте неизменным во всех ваших программах, что если у вас есть последовательность, она никогда не будет нулевой. Он всегда инициализируется пустой последовательностью или какой-либо другой подлинной последовательностью.
Если последовательность никогда не равна нулю, то, очевидно, вам не нужно ее проверять.
источник
null
) , обобщающей весь цикл на ЖК - дисплееEnumerable
(как использование??
будет ), б) требовать добавления метода расширения к каждому проекту, или в) требовать исключенияnull
IEnumerable
s (Pffft! Puh-LEAZE! SMH.) в начале (cuz,null
означает N / A, тогда как пустой список означает, что он применяется, но есть в настоящее время, ну, пусто !, то есть Empl. может иметь Комиссионные, которые N / A для non-Sales или пустые для Sales, когда они не заработали).На самом деле для этого @Connect есть запрос функции: http://connect.microsoft.com/VisualStudio/feedback/details/93497/foreach-should-check-for-null
И ответ вполне логичный:
источник
Вы всегда можете проверить это с помощью пустого списка ... но это то, что я нашел на веб-сайте msdn
источник
Это не лишнее. Во время выполнения элементы будут преобразованы в IEnumerable, и будет вызван его метод GetEnumerator. Это приведет к разыменованию элементов, которые не работают
источник
IEnumerable
и 2) Это дизайнерское решение сделать ее бросанием. C # мог легко вставить этуnull
проверку, если разработчики сочли это хорошей идеей.Вы можете инкапсулировать нулевую проверку в методе расширения и использовать лямбда:
Код становится:
Если может быть еще более кратким, если вы хотите просто вызвать метод, который принимает элемент и возвращает
void
:источник
Вам это нужно. Вы получите исключение при
foreach
доступе к контейнеру, чтобы в противном случае настроить итерацию.Под обложками
foreach
использует интерфейс, реализованный в классе коллекции, для выполнения итерации. Общий эквивалентный интерфейс находится здесь .источник
Тест необходим, потому что, если коллекция имеет значение NULL, foreach вызовет исключение NullReferenceException. На самом деле попробовать это довольно просто.
источник
второй бросит
NullReferenceException
с сообщениемObject reference not set to an instance of an object.
источник
Как упоминалось здесь, вам нужно проверить, не является ли он нулевым.
источник
В C # 6 вы можете написать sth вот так:
Это в основном решение Влада Бездена, но с использованием ?? выражение, чтобы всегда генерировать массив, который не является нулем и, следовательно, выживает после foreach, а не имеет эту проверку внутри скобки foreach.
источник