Как стать автором
Поиск
Написать публикацию
Обновить

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

Собственно потому и не используют, что есть довольно оптимизированный linq, который использует, но никто не заметил. static abstract тоже сомнительно, обычно статиком даже и не пользуются проще сделать класс обёртку и в нём нужные методы и свойства для расширения

Сомнительно, или нет, но static abstract/virtual использую довольно часто. Поначалу, пока не освоился, пожалуй даже чаще, чем стоило :) Это то, что вертелось на кончиках пальцев с появления паттерна фабрика, а быть может и паттернов, как таковых. Описывать паттерны не плодя сущности для бойлерплейта, а описывать их прямо в интерфейсах и использовать на аргументах дженериков, ну как это может быть не круто?! Мне очень нравится. Хотя готов признать, что дело вкуса.

Про незаметно оптимизированный линк отмечу, что почему-то вообще мало кто интересуется тем, что в репах мс лежит. И вообще как там что под капотом устроено. Даже что такое low level c# мне за много-много собеседований никто не ответил. Или мне так везет, или любознательность вышла из чата дотнет. Многие даже не заметили, что он опен сурс стал, а те кто заметил, не придали значения.

для меня статик выглядит как костыль, который закрывает некоторые архитектурные проблемы приложения, хотя может это прочто моя привычка всё разделять на объекты с данными и объекты которые эти данные обрабатывают, хотя проблем описанных в статье я с таким подходом не испытывал

моя привычка всё разделять на объекты с данными и объекты которые эти данные обрабатывают

Это же нарушение инкапсуляции.

А статический класс — это просто лаконичный аналог синглтона, позволяющий везде писать, например, Log.Warning() вместо Log.Instance.Warning().

Да, разделять данные и логику, это буквально попрание одного из трех китов. Хотя сейчас разных подходов пруд-пруди и это может быть "anemic domain model". А может быть "я художник, я так вижу" :) В любом случае, я лично больше люблю rich модели в домене.

У синглтона есть внутреннее состояние, которое он сохраняет от вызова к вызову. Если никаких данных от вызова к вызову хранить не нужно, логично подумать про статик. Кстати, весь линк - статик, это же все методы расширения. Инструментов масса и их все больше. Кому не надо, тому не надо.

Внедрение зависимостей, как его сейчас принято делать, не работает со static-классами. У меня получается, что классы, обрабатывающие данные, имеют только зависимости в полях.

а как же services.AddSingleton<T>()?

Не понимаю, как с помощью Singleton изобразить зависимость одного сервиса от другого, чтобы фрейморк эти зависимости мог разрешать. Обычно же зависимости передаются через конструктор. Или AddSingleton умеет работать со static constructor, я такого ещё не видел.

я лично больше люблю rich модели в домене

Не могу сообразить, как это будет выглядеть с зависимостями.
Вот например anemic модель

    public class Customer
    {
        public Customer(string name)
        {
            Name = name;
        }

        public string Name { private set; get; }
    }

    public class CustomerService : ICustomerService
    {
        ILogger _logger;
        ICustomerRepository _repository;

        public CustomerService(ILogger logger, ICustomerRepository customerRepository)
        {
            _logger = logger;
            _repository = customerRepository;
        }

        public void Save(Customer customer)
        {
            _repository.Save(customer);
            _logger.Log("customer saved");
        }
    }

Если делаем rich-объект Customer и переносим метод Save в него, конструктор доменного объекта должен принимать зависимости?

var customer = new Customer("John Smith", logger, customerRepositoty);

Выглядит некрасиво.

Если какой-то тип можно было складывать через "+", например DateTime, то теперь он реализует нужный интерфейс.

Только вот в DateTime и прочие временные классы/структуры эту обобщенную математику почему-то забывают добавить уже третью подряд версию фреймворка, да и про то, что в .NET 10 это появится что-то не слышно. Вроде бы это можно будет решить за счет новых экстеншенов, но действительно странно не добавить такое в BCL.

потому что сложение в DateTime это не совсем сложение, по сути вы можете сложить DateTime и TimeSpan, добавить количество лет, месяцев, дней, часов, минут секунд, но не два DateTime, а вещи типа умножения DateTime, взятия в степень так вообще дичь. Если уж так надо, то переведите DateTime в секунды и складывайте. Его не добавляют, потому что не понятна цель этого

Да для DateTime нет замкнутой операции. Но вот TimeSpan абелева группа по сложению, однако тоже не добавили обобщенные интерфейсы.

Сложение с точки зрения C# - это всегда "совсем" сложение. При описании оператора можно складывать, вычитать, умножать и делить все, что угодною Там же еще остаток от деления, сдвиг и унарные операторы. И все это можно с любыми типами, кроме исходного описать. Можно, к примеру, унарный плюс сделать преобразователем в строку. Или правым оператором сдвига строку указать, а результатом вообще самописный класс пристегнуть https://learn.microsoft.com/en-us/dotnet/api/system.int32.system-numerics-iadditionoperators-system-int32-system-int32-system-int32--op_addition?view=net-9.0

Так вот, можно вычитание для двух DateTime сделать и на выходе TimeSpan сделать. Ну а сложение уже DateTime с TimeSpan и DateTime результатом.

Все операции описываются отдельными интерфейсами, поэтому если возведение в степень не вписывается в логику типа, так и реализовывать ее не надо.

спасибо за статью, прочитал и вспомнил как я пытался это сделать и теперь понимаю почему тогда не получилось)) попробую новым способом

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