C# - pattern matching - many discards
Код отвлечённый, как я сказал. Просто нужен был любой пример с методом без параметров и с парой параметров, однострочный и в несколько строчек. Главное, что методы не определяются где-то в другом месте класса, а пишутся тут же лямбдами. А ленивая инициализация - это вообще уже давно привычная тема. Чем код не нравится?
насколько быстро можно будет читать код другого человека?
Мой код можно понять очень быстро, т.к. всё компактно и в одном месте. А вот если распихать его кусками по всему классу, то придётся прыгать по нему, теряя контекст.
Если метод большой - 5+ строчек, то я выношу его отдельно. А так у меня в проекте часто встречается, что нужно инициализировать объект в том числе кучкой коротких методов (делегаты). Выписывать их где-то вдалеке, а не по месту - просто плодить лапшу в коде.
Если не нравится конкретный код, вот можно более абстрактный
Person somePerson; public Person SomePerson => somePerson ??= new() { Property1 = 20, Property2 = _ => ..., Property3 = (param1, param2) => { ... ... ... }, };
Мой код можно понять очень быстро
Пропущено "МНЕ". Обычно код читается за один проход без задержек. Здесь же нужно задумываться на любой строке.
Обычно код читается за один проход без задержек.
Что-то тривиальное.
Фабрика фабрик у вас тоже за один проход, без задержек?
Здесь же нужно задумываться на любой строке.
У вас вызывают затруднения одна однострочная функция и одна двухстрочная? Или в присвоении константы вы видите скрытые смыслы? Может, оператор ??= слишком нов и загадочен для вас? Ленивая инициализация - откровение? ))
Общую концепцию я бы не стал трогать, как и правильную последовательность вызовов.
Но подобную конструкцию вижу в первый раз "Property2 = _ =>"
И каким образом
public Func<object, string> Property2 { get; set; }
превращается в
public string Property2 { get; set; }
пока не додумался Как и откуда берутся параметры для Property3?
Фабрика фабрик у вас тоже за один проход
Подобные конструкции создают извращенцы, которые пока по счастью не попадались.
Общую концепцию я бы не стал трогать, как и правильную последовательность вызовов.
Но подобную конструкцию вижу в первый раз "Property2 = _ =>"
И каким образом
public Func Property2 { get; set; }
превращается в
public string Property2 { get; set; }
пока не додумался Как и откуда берутся параметры для Property3?
Всё там нормально - никаких
public string Property2 { get; set; }
там нет. Name и Condition это делегаты, возвращающие строки. Просто название неудачное, что непонятно, что это не просто свойства.
Параметры берутся при вызове этих делегатов:
string name = SomePerson.Name(anyAge); string condition = SomePerson.Condition(id, "alive");
Я вам ещё раз говорю - не привязывайтесь сильно к коду. Я лишь хотел показать, как будет выглядеть то или иное использование. Первый случай - нужен делегат с параметров, а у меня есть вариант метода или лямбды без параметра. Ну я и использую дискард. Второй случай - не совсем верно я по памяти написал. Но тут просто хотел показать вариант, когда метод не однострочный и с более, чем одним параметром - т.е. вроде бы громоздко должно выглядеть, но на самом деле не очень.
По идее, если всё свойство или метод укладываются в один экран, то вы не теряете контекст работы этого свойства - вы видите всё от и до. А вот когда у вас ссылки на методы, разбросанные по классу, то вам надо прыгать на эти ссылки, чтобы глянуть, что там происходит - вы теряете контекст.
Фабрика фабрик у вас тоже за один проходПодобные конструкции создают извращенцы, которые пока по счастью не попадались.
Да ладно? А по мне, так подавляющая часть всяких инверсий зависимостей - это как раз извращения. Чтобы понять, как работает та или иная хрень, написанная с помощью инверсий, нужно либо попрыгать по классам, либо иметь возможность открыть штук 5-10 окон с кодом в параллельном режиме (не знаю ни одной IDE с такой возможностью), чтобы видеть весь код сразу. Особенно этим страдают всякие инжекции и шаблонные методы. Оно может хорошо работает, но понять эту хрень зачастую очень сложно, особенно когда создатель почти не оставил комментариев. И особенно если эти инженкции не в чистом виде, как в рафинированных примерах, а разбавлены прочим кодом и паттернами.
В примере моего реального приложения там были объекты-модели для гуёвых контролов, и у каждой такой модели была пачка делегатов для установки свойств гуёвого контрола в зависимости от условий. И вот методы для этих делегатов были в основном 1-4 строчными. И мне было проще и понятнее писать эти методы прямо в создании этих моделей для контролов, чем раскидывать их по модели всей гуёвой формы. Т.е. не так
FormModel { Control1 Control2 ... Methods for Control1 Methods for Control2 ... }
а вот так
FormModel { Control1 { Methods for Control1 } Control2 { Methods for Control2 } ... }
В реальности в модели формы ещё полно другого кода, так что делегаты там просто теряются, и получается, что инициализация каждого контрола раскидана по всей модели формы.
Свой пример чего? :)
Твой пример - неместируемое говно.
А если учесть, что
Name и Condition это делегаты
так это еще и хрен поймешь в каком месте программы и за что отвечает сей объект.
Person somePerson; public Person SomePerson => somePerson ??= new() { Age = 4, Name = _ => Age == 4 ? "car" : "some other vehicle", Condition = (Guid id, string defaultCondition) => { return id.GetHashcode() % 2 == 0 ? "Tank Full" : "Damaged engine"; }, }
а потом так:
Person somePerson; public Person SomePerson => somePerson ??= new() { Age = 2, Name = _ => Age > 0 ? "Lion" : "Bird", Condition = (Guid id, string defaultCondition) => { var realAge = GetWhatEverById(id); return realAge > 100 ? "Healthy" : "Pink"; }, };
Флаг в руги к крест на могилу при отладке этого говна.
Я спросил ваш вариант, если у объекта есть делегаты, которые нужно инициализировать. Вы же не против делегатов в принципе? У меня делегаты инициализируются лямбдами прямо в инициализаторе объекта, при этом инициализация ленивая. Ещё можно написать отдельные методы и назначить их делегатам. Можно в инициализаторе объекта, а можно после вызова конструктора. Тут не вопрос, будут ли делегаты в принципе - они есть, и вы с этим поделать ничего не можете.
В чём проблема отладки? У вас отладчик в этих строчках кода не остановится?
Чтобы вы не придирались к возможному наобум придуманному конкретному коду, я написал более абстрактно, где обозначил, что важно лишь то, где определены функции, которыми инициализируются объекты. Но вы все проигнорировали это, а стали прицепляться к невылизанности кода. Вместо этого конкретного кода может быть любой другой. Поэтому я и сказал - вставьте свой по вкусу, ваш вариант. Главное, что тут у объекта свойство-делегат, и нужно ему назначить какой-то метод.
Вы же не против делегатов в принципе?
Я против делегатов. Делегаты дают настолько большую свободу использования и интерпритации, что ну его нахрен. Вообще, я не припомню ни одного случая, когда было бы разумно использовать делегаты... ну кроме пожалуй call back функций, которые не используются уже лет 500.
и вы с этим поделать ничего не можете.
Убить того, кто везде с поводом и без ляпая делегаты :)
В чём проблема отладки? У вас отладчик в этих строчках кода не остановится?
Отладчик в этих строчках остановится. А вот в каких местах эти делегаты будут вызваны? Какие там зависимости? Как и самое главное что при таком подходе отлаживать?
Собственно говоря, с таким подходом вообще не нужены ни классы, ни структура, ни архитектура. Просто желаешь
God-объект и добавляешь в него делегаты с разными параметрами. Дальше твоя задача просто вызывать эти делегаты в нужной последовательности. Ну и проинициализировать твой God-объект :)
Я против делегатов. Делегаты дают настолько большую свободу использования и интерпритации, что ну его нахрен. Вообще, я не припомню ни одного случая, когда было бы разумно использовать делегаты... ну кроме пожалуй call back функций, которые не используются уже лет 500.
Гуй. В том числе гуёвые модели в паттернах типа MVVM, MVP, MVC и т.п.
И в принципе все случаи, когда надо реагировать на какое-то событие - пришли данные в канал, добавились данные в БД, какой-то чувак нажал на кнопку. Альтернатива какая событиям? В бесконечном цикле отслеживать флаги наступления этих событий?
и вы с этим поделать ничего не можете.Убить того, кто везде с поводом и без ляпая делегаты :)
А я люблю делегаты! Я их на хлеб каждое утро мажу, и даже засыпаю с парой больших плюшевых делегатов в обнимку.
Вообще, вы казались раньше, со стороны, крутым дядей-программистом. Сеньёр-помидор, гроза джунов, отец миддлам. А в шкафу банальные скелеты - зачморён делегатами. Это, кстати, и остальных тут типа-крутых типа-сеньёров касается. ))
Гуй. В том числе гуёвые модели в паттернах типа MVVM, MVP, MVC и т.п.
Там используются event'ы. Эвенты используют делегаты, но разница между ними огромна.
Альтернатива какая событиям?
Эвенты используют делегаты, но разница между ними огромна.
Если в 2-х словах:
An Event declaration adds a layer of abstraction and protection on the delegate instance. This protection prevents clients of the delegate from resetting the delegate and its invocation list and only allows adding or removing targets from the invocation list.
Просто для сеньоров-помидоров SOLID не пустой звук.
Тут не вопрос, будут ли делегаты в принципе - они есть, и вы с этим поделать ничего не можете.
Вот в этом и есть главная проблема.
Когда в Си пользовали косвенные вызовы процедур/функций, то это как то еще можно было понять (и простить )
Но в шарпе? и повсеместно...
Уверен, что если Вы чуть больше подумаете в этом направлении (убрать нахрен эти делегаты), то наверняка найдете более разумное решение.
А по мне, так подавляющая часть всяких инверсий зависимостей - это как раз извращения.
Когда и я так думал, когда привык ставить точку останова в конструкторе и смотреть откуда приходят все параметры.
Но времена меняются и слабое связывание оказывается гораздо полезнее.
Наверняка и MediatR и FluentValidation и пр. считаете извращениями вместе с чистым кодом и чистой архитектурой. Народ просто хочет подзаработать и махает этим перед носом тупых осликов.
А мы умные, будем делать правильно без всей этой надуманной научной чуши.
Параметры берутся при вызове этих делегатов:
Да, потом уже дошло это извращение. Обычно ожидается увидеть инициализированный объект в подобном случае и инициализированный данными, а не какой то фигнёй.
там были объекты-модели для гуёвых контролов, и у каждой такой модели была пачка делегатов для установки свойств гуёвого контрола в зависимости от условий.
Ладно, не будем придираться что МОДЕЛЬ имеет КОНТРОЛЫ. Но получается, что каждый контрол работает по разному в зависимости от того где он используется. Что по идее приводит к тому, что и контролы и модели становятся сильно связанными.