Есть ли более приятный способ сделать следующее:
мне нужно проверить наличие null в файле. Заголовки, прежде чем продолжить цикл
if (file.Headers != null)
{
foreach (var h in file.Headers)
{
//set lots of properties & some other stuff
}
}
Короче говоря, писать foreach внутри if из-за уровня отступов в моем коде выглядит немного некрасиво.
Что-то, что оценило бы
foreach(var h in (file.Headers != null))
{
//do stuff
}
возможный?
Ответы:
В качестве небольшого косметического дополнения к предложению Руне вы можете создать свой собственный метод расширения:
public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> source) { return source ?? Enumerable.Empty<T>(); }
Тогда вы можете написать:
foreach (var header in file.Headers.OrEmptyIfNull()) { }
Меняем название по вкусу :)
источник
Предполагая, что тип элементов в file.Headers равен T, вы можете сделать это
foreach(var header in file.Headers ?? Enumerable.Empty<T>()){ //do stuff }
это создаст пустое перечислимое значение T, если file.Headers имеет значение null. Однако, если тип файла принадлежит вам, я бы
Headers
вместо этого рассмотрел возможность изменения получателя .null
является значением unknown, поэтому, если возможно, вместо использования null в качестве «Я знаю, что элементов нет», когда значение null на самом деле (/ изначально) следует интерпретировать как «Я не знаю, есть ли какие-либо элементы», используйте пустой набор для отображения что вы знаете, что в наборе нет элементов. Это также будет DRY'er, поскольку вам не придется так часто выполнять нулевую проверку.ИЗМЕНИТЬ в качестве продолжения предложения Джонса, вы также можете создать метод расширения, изменив приведенный выше код на
foreach(var header in file.Headers.OrEmptyIfNull()){ //do stuff }
В случае, если вы не можете изменить получатель, это было бы моим предпочтением, поскольку оно более четко выражает намерение, давая операции имя (OrEmptyIfNull)
Упомянутый выше метод расширения может сделать некоторые оптимизации невозможными для обнаружения оптимизатором. В частности, те, которые связаны с IList с использованием перегрузки метода, могут быть устранены
public static IList<T> OrEmptyIfNull<T>(this IList<T> source) { return source ?? Array.Empty<T>(); }
источник
null
) вырождения всего цикла на ЖК-дисплейIEnumerable<T>
(как при использовании ?? будет), б) потребует добавления метода расширения к каждому проекту или в) потребует избегатьnull
IEnumerables
(Pffft! Puh-LEAZE! SMH.) с самого начала (cuznull
означает N / A, тогда как пустой список означает, что он применим, но в настоящее время, ну, пусто !, т. е. Сотрудник может иметь Комиссионные, которые Н / Д для не-продаж или пустые для Продаж, когда он их не заработал).IEnumerable
более строгими, чемforeach
требования, но менее строгими, чем требованияList<T>
в ответе, на который вы ссылаетесь. Которые имеют такое же снижение производительности при проверке, является ли перечисляемое значение null.List<T>
.Честно говоря, советую: просто обсасывайте
null
тест.null
Тест только а ,brfalse
илиbrfalse.s
; все остальное будет включать в себя гораздо больше работы (тесты, задания, дополнительные вызовы методов, нет необходимостиGetEnumerator()
,MoveNext()
,Dispose()
итератора, и т.д.).if
Тест прост, очевидно, и эффективный.источник
«if» перед итерацией - это нормально, некоторые из этих «красивых» семантик могут сделать ваш код менее читабельным.
в любом случае, если отступ вам мешает, вы можете изменить if, чтобы проверить:
if(file.Headers == null) return;
и вы попадете в цикл foreach только тогда, когда в свойстве headers есть истинное значение.
Другой вариант, о котором я могу подумать, - это использование оператора объединения с нулем внутри цикла foreach и полное исключение проверки на нуль. образец:
List<int> collection = new List<int>(); collection = null; foreach (var i in collection ?? Enumerable.Empty<int>()) { //your code here }
(замените коллекцию своим истинным объектом / типом)
источник
Использование оператора Null-conditional и ForEach (), который работает быстрее, чем стандартный цикл foreach.
Однако вы должны передать коллекцию в список.
listOfItems?.ForEach(item => // ... );
источник
Я использую небольшой метод расширения для этих сценариев:
public static class Extensions { public static IList<T> EnsureNotNull<T>(this IList<T> list) { return list ?? new List<T>(); } }
Учитывая, что заголовки относятся к списку типов, вы можете сделать следующее:
foreach(var h in (file.Headers.EnsureNotNull())) { //do stuff }
источник
??
оператор и сократить оператор возврата доreturn list ?? new List<T>;
null
в вашем образцеfile.Headers.EnsureNotNull() != null
не нужен, и даже ошибается?В некоторых случаях я бы предпочел немного другой, общий вариант, предполагая, что, как правило, конструкторы коллекций по умолчанию возвращают пустые экземпляры.
Лучше было бы назвать этот метод именем
NewIfDefault
. Это может быть полезно не только для коллекций, поэтому ограничение типаIEnumerable<T>
может быть избыточным.public static TCollection EmptyIfDefault<TCollection, T>(this TCollection collection) where TCollection: class, IEnumerable<T>, new() { return collection ?? new TCollection(); }
источник