Здравствуй, читатель. Я хотел бы рассказать, как использовать преимущества разных языков программирования среды dotnet в одном проекте. Рассматривать будем одно нововведение, а именно реализацию интерфейсов с разными универсальными экземплярами ( в версии F # 5.0).
Это «фича» может сделать код более коротким и гибким в работе. Сразу стоит сказать, что с F # я знаком слабо, поэтому стиль написания кода на нём может быть не привычен для опытного разработчика.
Начнём.
С формулируем задачу: Разработать библиотеку классов, которая должна следить за изменением температуры и выводить информацию о том, что изменение произошло. Предусмотреть возможность вывода значения температуры в разных единицах измерения.
Я предложу свою реализацию с использованием F# .
Для начала создадим свои структуры данных, которые будут хранить в себе значение температур, но в разных единицах измерениях.
Создадим библиотеку классов для F# .
В ней несколько файлов: Struct и Temperature . В файле Struct определены структуры данных, с которыми будет производится некоторые действия. В файле Temperature заложена логика взаимодействия со структурами.
Структуры есть. Но стойте, везде присутствует одно и тоже поле value . К тому же, не очень будет удобно работать со структурами в ситуациях, когда точно не известен её тип. Но F # мультипарадигмальный язык программирования. Поэтому перепишем чуть-чуть структуры.
Вот. Уже другое дело. Теперь мы сможем работать с структурами как с интерфейсом. Привет паттерн «Стратегия».
Далее перейдём к файлу Temperature .
В нём как раз и будет использоваться обобщенный интерфейс и класс с разными его реализациями.
Сам интерфейс будет довольно простым.
То есть всего 3 метода, которые в зависимости от типа ` T будут конвертировать значение в другую структуру.
Теперь создадим класс и реализуем этот интерфейс с разными типами данных. Получилось что-то вроде такого:
И так, что тут происходит.
Создался класс Temperature с одним полем value типа ITemperature (общего интерфейса наших структур) и конструктором, принимающим объект ITemperature (по сути, нашу структуру) и записывает её в своё поле.
А также 3 раза реализовался интерфейс IConvertable от всех наших типов структур ( C , F , K ), которые были созданы нами ранее в файле Struct . И сразу определена логика работы каждого метода этого интерфейса. Честно скажу, такая реализация очень упрощается работу и уменьшает объём кода.
Теперь создадим библиотеку классов, но уже на C # . По факту это лишнее, но мне хотелось проверить, как сгенерированные классы для F # будут вести себя в проекте на C #
И так, добавился проект на C # .
EventBroker – это своеобразный менеджер вызова событий. Он представляет из себя статичный класс.
EventHandlerMonitorTemperature – класс для передачи информации событий в классы, которые подписались на изменения.
MonitorTemperature – класс, работающий с библиотекой на F# .
Полный код и реализацию можно посмотреть в моём репозитории на Github .
Самое главное, где использовалась наша обсуждаемая «фича»:
Это конструктор класса EventHandlerMonitorTemperature, в который приходит объект класса Temperature из нашей библиотеки на F # . В нём достаём ссылку на структуру ( structTemp ). И далее используя Pattern Matching определяем её тип. В каждом « case » создаём переменную типа структуры, которая нас интересует и дальше просто вызываем уже реализованные методы в классе Temperature . По факту класс Temperature приводится к интерфейсу IConvertable<”наша структура”> и вызывается тот метод с той реализацией, которая соответствует этому интерфейсу.
Для проверки создадим небольшое консольное приложение. Код будет следующим:
В теле метода Main используется 3 метода класс EventBroker , которые записывают температуру кипения в разных единицах измерения.
Результатом выполнения кода станет следующее:
То есть все наши значения были корректно переведены в те единицы измерения, которые нас интересовали.
Я только начал погружаться в мир F # и хочу сказать одно: он очень неплох. Его стоит использовать в «продакшене» и можно использовать в связке с C # без всяких проблем, используя преимущества этих языков.