Как стать автором
Обновить

Комментарии 19

Фига се воды разлили. Достаточно ведь было сказать "нет, т.к. foreach не умеет игнорировать null, да и не обязан, в общем-то".

А мне интересно иногда копнуть вглубь или вширь.


В данном случае получилось вширь — не просто сказали, что нельзя, а посмотрели чуть шире — рассказали историю доработок (как, что, зачем), посмотрели на реальные примеры ошибок.


Но, конечно, на вкус и цвет. Впрочем, как и всегда. :)

Знаете, я понимаю мотивацию статьи, в конце-концов, вы рассказываете про анализатор, а не только про особенности языка. Но реальная польза состояла в двух фактах:
— объяснении, что foreach это синтаксический сахар для…
— объяснении, что оператор… это синтаксический сахар для…

Все остальное уже было понятно на этом этапе, и вот честное слово, никакой глуби больше в этой теме вообще нет. То есть воды все-таки чуть многовато. На мой вкус, да.

Так про "вглубь" я и не говорил — там выше ссылочка на другую статью. :)


Тут разные аспекты — немного про foreach (откуда там NRE), немного про историю доработок, немного — про примеры ошибок. Мне, например, было интересно посмотреть на эти ошибки — другим людям тоже бывает. Для того они и приведены.


Так или иначе, спасибо за мнение. :)

>Так про «вглубь» я и не говорил
Так по-моему ее тут и нет. Ну т.е. если посмотреть на похожие языки (в голову первым приходит груви), то там будет ровно все тоже самое. Ну посудите сами,?.. это типа «безопасный доступ» к полю или методу объекта по ссылке. Если ссылка (пусть будет a) нулл, то a.b.c просто упадет сразу, а a?.b?.c вернет нулл. То есть,?.. оно от нуллов не избавляет, и ведет себя плюс-минус совершенно так же.

А так текст вообще норм, ну чуток может растянут, немножко.

Все базируется на простых фактах.


  • Все ли понимают, что?.. может вернуть null. Думаю, все. Никто не спорит с тем, что Вы написали выше. :)
  • Все ли понимают, что если null будет использоваться в перечислимом выражении foreach, словам NRE? Не все.
  • Все ли понимают, почему? Не все.
  • Ошибаются так люди? Да.
  • А пруфы есть? Есть.

Ergo, это может быть интересно тем, кто чего-то не знает. Все просто как 5 копеек. :)

Я немного о другом думал. Как сделать пост, который бы был интересен тем, кто не все знает, и не выглядел как содержащий много воды для остальных? Рецепт не рецепт, но по крайней мере идея:
— пункт 1
— пункт 2
— если для вас это очевидно, можете дальше не читать,
но имейте в виду, что вот мы для вас написали правило анализатора
— более длинная история

Ну как-то так.

Да, такая структура возможна и работает. Иногда прибегаю к ней.

Кажется, что вариант с использованием оператора?.. более безопасный. Но так ли это на самом деле?
Простите, а кому так кажется? Совершенно очевидно, что "?." может вернуть null, этот оператор, собственно, для этого и предназначен. А если он вернёт null, то foreach навернётся. В чём здесь тайная магия?
Простите, а кому так кажется?

Тем, кто пишет подобный код, например.


Совершенно очевидно, что

Как показывает жизненный опыт, что очевидно одному, не обязательно очевидно другому. :)

Всегда пишу как в последнем примере. Это очевидно.

Угу, у себя в коде тоже сдефайнил метод NeverNull() с аналогичным кодом. И обратный EmptyToNull(). Второй особенно полезен для API объектов... При json сериализации null поля опускаются.

НЛО прилетело и опубликовало эту надпись здесь

Действительно, интересный вопрос. Нужно будет попробовать эксперимента ради.


Если кто попробует раньше — отпишитесь в тред. :)

Я бы за такой код на ревью сразу бил по рукам
Я поспорю, что проблема очевидна, потому что я не знаю ни одного C# разработчика, который не знает, что Enumerable в foreach не должен быть null.

> не используйте оператор?.. в перечислимом выражении foreach прямо или косвенно — это только иллюзия безопасности;
foreach (var item in obj?.collection ?? Enumerable<T>.Empty()) { .. }

Что вы сами и привели в качестве примера (да, я читал статью по диагонали...)
Что вы сами и привели в качестве примера (да, я читал статью по диагонали...)

Неточности формулировки. :) Имел ввиду косвенное использование — когда результат?.. записывается в переменную, которая затем используется в перечислимом выражении.

Полезная статья для новичков, кто, возможно, будет иметь такие проблемы. Как уже отметили другие «старички» — действительно, странно использовать оператор .? в foreach

Единственное, что я бы исправил — это как записан блок
  if (collection != null)
  {
    foreach (var item in collection.Where(predicate))
      Console.WriteLine(item);
  }

А точнее применение фигурных скобок. Отталкиваясь от стиля, заданного изначально, если внутри цикла одно действие — мы не ставим фигурных скобок, я бы опустил этот момент и в условии, в результате получилось бы:

  if (collection != null) 
      foreach (var item in collection.Where(predicate))
        Console.WriteLine(item);

Получилось бы визуально более коротко, и еще проще, чем в варианте с ?? Enumerable.Empty()

во всех вменяемых стайлгайдах многострочный if всегда обрамляется скобками. а если следовать правилу fail-fast то после if должен стоять return.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий