Здравствуйте, -n1l-, Вы писали:
AVK>>Нет и не будет. Ибо зло в чистом виде N>почему?
Потому что при чтении кода linq выражения человеком обычно воспринимаются как pure. И если на самом деле там внутри меняется внешнее состояние, это сильно снижает читаемость кода. Что есть зло.
А в зло в чистом виде, потому что никакого преимущества такой метод по сравнению с оператором foreach не дает, только лишний синтаксический шум и маскировка под чистые методы.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, -n1l-, Вы писали:
N>>Как вам такое?
AVK>Присутствует под названием GetValueOrDefault. Или я что то не так понял? AVK>
J> был бы полезен
Оба не нужны.
Серьёзно, давайте всё-таки предлагать фичи по принципу "есть _реальный_ сценарий использования", а не "что б ещё такое переподвывернуть?"
Для последнего php с js есть, развлекайся — не хочу
Есть сценарий — не вопрос, можно обсудить. Нет — я бы выкидывал без сожалений. Мы ж не за количеством методов гонимся
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, -n1l-, Вы писали:
N>>Сразу до кучи — ForEach для IEnumerable запилили?
AVK>Нет и не будет. Ибо зло в чистом виде
Как вы поступаете с большими выражениями?
Создаете временную переменную?
И что так лучше читается вместо добавления одного метода, который этот форыч инкапсулирует?
Здравствуйте, Jack128, Вы писали:
J>А вот чтоб переписать код ниже без метода Do — нужно заводить отдельный метод
Во всех проектах, в которых я участвовал, подобный код немедленно выпиливается из проекта с подробной лекцией о том, почему так делать нельзя.
Если коротко и цензурно, то код пишут не чтоб потешить ЧСВ, а чтоб через годика 4 его смог за полминуты поправить только что принятый джуниор. И чтоб при этом код не превратился в какашку.
Серьёзно, это прям таки классический пример, почему код нельзя писать в solution-driven стиле.
Допустим, Process чуть позже станет фильтровать objs или получать только последний из них. Соответственно, большая часть AdditionalData будет заполнена зря.
Зашибись как сэкономили, да?
Вы точно уверены, что хотите поддерживать код с такими потенциальными багами?
Ну и как всегда правильный варинт:
1. признать, что текущий дизайн — отстой, т.к. вынуждает лепить костыли в самых тривиальных случаях.
2. Сделать рефакторинг под реальный сценарий использования. Например, вытащить тело цикла в отдельный метод.
3. В будущем на code review показывать разработчику, что в 99% случаев необходимость в костылях к стандартным конструкциям языка означает криво спроектированное API. Правильный способ — не прикрыть текущую ситуацию штукатуркой, а чинить исходную проблему.
Здравствуйте, Sinix, Вы писали: S>3. В будущем на code review показывать разработчику, что в 99% случаев необходимость в костылях к стандартным конструкциям языка означает криво спроектированное API. Правильный способ — не прикрыть текущую ситуацию штукатуркой, а чинить исходную проблему.
Это в мирках где бизнес-логика настолько простая, что все что нужно делать — использовать стандартные методы фреймворка?
Здравствуйте, -n1l-, Вы писали:
S>>3. В будущем на code review показывать разработчику, что в 99% случаев необходимость в костылях к стандартным конструкциям языка означает криво спроектированное API. Правильный способ — не прикрыть текущую ситуацию штукатуркой, а чинить исходную проблему.
N>Это в мирках где бизнес-логика настолько простая, что все что нужно делать — использовать стандартные методы фреймворка?
Э-э-э, пост внимательней читай
речь была про
необходимость в костылях к стандартным конструкциям языка
,
не про хелперы для фреймворка.
Предложенный Do() означает, что девелоперу влом написать foreach. Или что дизайн API вынуждает вырезать гланды с другой стороны, как в примере с GetAdditionalData().
И таки да, костяк БЛ практически никогда не вылезает за if/else/foreach + хелперы для "on A,B,C changed — do Y", всё страшное прячется на уровень ниже, в методы, которые разруливают конкретные случаи. Точнее, оно так может быть записано. А на практике я видел всё — от кодогенерации конечных автоматов в рантайма и до логики в 5-6 килострок на linq. Но это не значит, что код надо писать так
Это если мы конечно о типовой бухгалтерско-банковской опердени говорим, не о экзотике типа реалтайма/каналах связи и о прочей инфраструктурщине.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, Jack128, Вы писали:
J>>А вот чтоб переписать код ниже без метода Do — нужно заводить отдельный метод S>Во всех проектах, в которых я участвовал, подобный код немедленно выпиливается из проекта с подробной лекцией о том, почему так делать нельзя.
S>Если коротко и цензурно, то код пишут не чтоб потешить ЧСВ, а чтоб через годика 4 его смог за полминуты поправить только что принятый джуниор. И чтоб при этом код не превратился в какашку.
S>Серьёзно, это прям таки классический пример, почему код нельзя писать в solution-driven стиле. S>Допустим, Process чуть позже станет фильтровать objs или получать только последний из них. Соответственно, большая часть AdditionalData будет заполнена зря. S>Зашибись как сэкономили, да?
хм, а то что большая часть объектов MyObj тоже будет создана зря тя не волнует? Если не волнует, то как бы двойные стандарты уместны в политике, но не в программировании. Если же волнует, то по твоей логике вообще все методы, фильтрующие IEnumerable — аЦЦтой ибо все отфильтрованные объекты созданы зря.
S>Вы точно уверены, что хотите поддерживать код с такими потенциальными багами?
Где потенциальный баг? Пока ты привел аргумент по производительности.
S>Ну и как всегда правильный варинт: S>1. признать, что текущий дизайн — отстой, т.к. вынуждает лепить костыли в самых тривиальных случаях.
Не, тут я всегда за, сам люблю оцтоить дизайн, особенно чужой :-D S>2. Сделать рефакторинг под реальный сценарий использования. Например, вытащить тело цикла в отдельный метод.
Он вроде и так в отдельном методе, метод Proccess только из цикла и состоит. S>3. В будущем на code review показывать разработчику, что в 99% случаев необходимость в костылях к стандартным конструкциям языка означает криво спроектированное API. Правильный способ — не прикрыть текущую ситуацию штукатуркой, а чинить исходную проблему.
Смотрю во все глаза
Здравствуйте, Jack128, Вы писали:
S>>Допустим, Process чуть позже станет фильтровать objs или получать только последний из них. Соответственно, большая часть AdditionalData будет заполнена зря. J>хм, а то что большая часть объектов MyObj тоже будет создана зря тя не волнует?
Не волнует, т.к. из публичного контракта и сценария использования следует, что GetAdditionalData() — "тяжёлый" метод и должен вызываться лениво, только при необходимости. Если это не так — двойной косяк в дизайне: мы пишем костыли чтоб сэкономить на том, на чём вообще нет смысла экономить.
J> Если не волнует, то как бы двойные стандарты уместны в политике, но не в программировании. Если же волнует, то по твоей логике вообще все методы, фильтрующие IEnumerable — аЦЦтой ибо все отфильтрованные объекты созданы зря. J>Где потенциальный баг? Пока ты привел аргумент по производительности.
Не, смотри про что речь: сам по себе перебор enumerable — ок.
перебор, который закладывается на то, что при вызове MoveNext() происходят какие-то побочные эффекты — прямой путь к тому, что ожидания не сработают
твой код аналогичен:
var x = GetX();
DoSomething(x);
var y = x.Y; - закладываемся на то, что Y заполнен в DoSomething().
Надеюсь, не надо спрашивать "что тут может пойти не так?"
Ну фигня же, а не хороший код, не согласен?
S>>Ну и как всегда правильный варинт: S>>1. признать, что текущий дизайн — отстой, т.к. вынуждает лепить костыли в самых тривиальных случаях. J>Не, тут я всегда за, сам люблю оцтоить дизайн, особенно чужой :-D
Не-не-не, ты не понял про что речь. Дизайн отстой не потому что автор его плохо написал, или потому что автор чего-то не знает (тут это очевидно не так). Дизайн отстой, потому что он очевидно используется не по делу.
Вот пока с этим не согласились — все дальнейшие движения не имеют смысла, т.к. получается спор из разряда "а слон кита заборет?".
Даже если заборет — получится фигня. Очень часто выходит так, что хорошего решения не находится и все варианты кроме исходного сам предлагающий постепенно сносит в мусорку. Вот как раз пример
Короче, "дизайн отстой" ни разу не значит "автор отстой", если было воспринято так — я сам отстой и мои извинения
S>>2. Сделать рефакторинг под реальный сценарий использования. Например, вытащить тело цикла в отдельный метод. J>Он вроде и так в отдельном методе, метод Proccess только из цикла и состоит.
Было:
void Process(IEnumerable<MyObj> objs) // обрабатываем их как то
{
foreach(var obj in objs)
{
...
}
}
тело цикла (троеточие) вынести в отдельны метод, или передать делегат параметром. Собсно AndrewVK выше предложил.
Здравствуйте, -n1l-, Вы писали:
N>Как вы поступаете с большими выражениями?
Какими большими выражениями? Выражения это pure код, там никаких foreach быть не может. А в foreach да, завожу столько переменных, сколько нужно.
N>И что так лучше читается вместо добавления одного метода, который этот форыч инкапсулирует?
Оператор foreach вместо метода совершенно точно делает код прозрачнее.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Какими большими выражениями? Выражения это pure код, там никаких foreach быть не может. А в foreach да, завожу столько переменных, сколько нужно.
ну типа — collection.Select(...).Where(...).GroupBy(...).SelectMany(...)
Вы это все в форыч засовываете?
Или отдельную переменную делаете, query например.
AVK>Оператор foreach вместо метода совершенно точно делает код прозрачнее.
Почему?
Здравствуйте, -n1l-, Вы писали:
N>ну типа — collection.Select(...).Where(...).GroupBy(...).SelectMany(...) N>Вы это все в форыч засовываете? N>Или отдельную переменную делаете, query например.
Обычно отдельную. А что?
AVK>>Оператор foreach вместо метода совершенно точно делает код прозрачнее. N>Почему?
Пошли по кругу? Потому что не содержит вызовов стороннего кода и не маскируется под линковские pure цепочки.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>