170 похожих чатов

Вечер добрый. Знает ли кто-нибудь решение для такой задачи? Есть класс, в

методе которого последовательно нужно вызвать несколько generic методов.
В сущности, результат выполнения Build() зависит от того, что передается в качестве типов в AddState:
public class StateMachineBuilder
{
public IConfiguration Build()
{
var builder = new InternalBuilder();
builder.AddState<FirstState>();
builder.AddState<SecondState>();
builder.AddState<ThirdState>();
return builder.Build();
}
}

Чтобы билдер как-то параметризировать, можно сделать StateMachineBuilder или Build() generic. Но состояний может быть много и это может превратиться в Build<TFirstState, TSecondState, TThirdState, ...........TN_ndState>, что выглядит сомнительно. Можно ли упаковать перечисление передаваемых типов или передать их другим путем?

14 ответов

14 просмотров

я перефразирую вопрос за тебя - можно ли типизировать конечный автомат? Да, можно.

в чем именно проблема? зачем делать метод Build обобщенным? внутри метода Build есть какое-то требование знать типы?

Я понял. Спрашивается про внешний метод Build а не про внутренний (который builder.Build). Типоаргументы тут - не лучшая идея, потому что тогда нужно либо делать миллион перегрузок (и то можно не угадать), либо заранее знать количество состояний. Вижу два относительно нормальных варианта: 1. Сделать нормальный шаблон билдер, т.е. вынести AddState<T> в метод, потом в методе Build дергать только _internalBuilder.Build. Соответственно в такой ситуации напрашивается вопрос - зачем вообще огород городить и почему бы пользоваться сразу InternalBuilder, зачем вообще эта обертка в виде StateMachineBuilder нужна, какая ее функция? 2. Передавать в функцию аргументом лямбду. Будет выглядеть так: public IConfiguration Build(Func<InternalBuilder, InternalBuilder> configure) { var builder = new InternalBuilder(); builder = configure(builder); return builder.Build(); } И вызываться как-то так: stateMachineBuilder.Build(x => { x.AddState<FirstState>(); x.AddState<SecondState>(); return x; }); Понятно что при желании можно в лямбду принимать не инстанс InternalBuilder, а какую-то обертку над нам, чтобы не показывать пользователю какой-то ненужный ему апи (например метод Build). Но что-то тут уже много оберток получается, нужно с позиции здравого смысла и требований к задаче оценивать, какие из них нужны, а какими можно принебречь.

Vogl- Автор вопроса
Kirill Tolmachev
Я понял. Спрашивается про внешний метод Build а не...

Конечных автоматов может быть много. Схема переходов одна, а вот состояния могут быть разные. По сути, я передаю набор состояний и строиться автомат заданного вида

Vogl- Автор вопроса
Kirill Tolmachev
Я понял. Спрашивается про внешний метод Build а не...

Ну с заданной лямбдой можно и без билдера. А по месту сконфигурировать. Идея в том, чтобы на месте вызвать билд, передав набор состояний в виде типов. Кроме аддстейт много всего вызывается в качестве расширений для аддстейт. Оно во всех случаях одинаково. Разница только в передаваемом типе. Я не стал указывать остальной обвес ибо на суть вопроса не влияет.

Vogl
Конечных автоматов может быть много. Схема переход...

У тебя противоречивые показания > Схема переходов одна, а вот состояния могут быть разные В общем, пока что мы решаем не ту проблему

Vogl- Автор вопроса
Ayrat Hudaygulov
У тебя противоречивые показания > Схема переходов...

Почему протевочиво? Есть состояния один, два, три. Переходим мы из один в два из два в три. То, что мы так двигаемся по состояниям, описывается а конфигурации. А вот один, два и три могут быть разными (в состояниях переход не описывается). Да и на суть вопроса это не влияет. Главное, есть женерик методы, как прокинуть им классы

Vogl
Почему протевочиво? Есть состояния один, два, три....

На суть вопроса это очень влияет, т.к. ты видишь цель и не видишь препятствий. А надо бы сделать шаг назад и рассказать что ты делаешь. Вот мы выяснили что у тебя набор функций-переходов один и тот же, и они даже составляют одну и ту же схему переходов (почему я и говорил что у тебя противоречивые показания). Но ты хочешь в разных автоматах менять лейблы стейтов? Даже твой запрос выполнить элементарно, интерфейсы вместо конкретных стейтов принимай в твоих функциях перехода.

Vogl- Автор вопроса
Ayrat Hudaygulov
На суть вопроса это очень влияет, т.к. ты видишь ц...

В качестве стейта мы передаем не значение, а тип. В сущности, тут интерфейс не думаю, что поможет. Если абстрагироваться от задачи, то есть условно, десять женерик функций, которые вызываются в определенном порядке. Важное значение имеют передаваемые женерикам типы. Параметризация - передаваемые типы. Их не получиться обернуть внутрь класса, по понятной причине, а делать метод билд женериком - плохой вариант.

Vogl
В качестве стейта мы передаем не значение, а тип. ...

Признаюсь честно, от имплементации ты не сильно абстрагировался и пересказал её ещё раз, не рассказав что же ты делаешь. А теперь покажи почему это не работает interface Step1 Interface Step2 Interface Step3 1to2 :: Step1 -> Step2 2to3 :: Step2 -> Step3 3to1 :: Step3 -> Step1 type SuperStep1 = interface Step1 type SuperStep2 = interface Step2 type RealStep1 =   interface Step1 type RealStep2 =   interface Step2 1to2 SuperStep1() SuperStep2() 1to2 MyStep1() MyStep2() Как видишь - функции перехода одни и те же - набор стейтов разный Теперь тебе надо показать почему это не решение и мы может наконец узнаем что же ты делаешь

Vogl- Автор вопроса
Ayrat Hudaygulov
Признаюсь честно, от имплементации ты не сильно аб...

Окей, как сюда запихнуть такое решение Foo<здесь параметризуемый класс>()?

Vogl- Автор вопроса

Окей, получается? Build<State1, State2, State3....>() { Foo1<State1>(); Foo2<State2>(); Foo3<State3>();.... }

Vogl
Окей, получается? Build<State1, State2, State3.......

билд в твоей постановке задачи лишний Смотри https://t.me/DotNetRuChat/1529288 Уже всё есть и никакого билда не надо

Похожие вопросы

Обсуждают сегодня

У меня это всегда вопрос вызывало.. Нафига писать код так, чтобы потом ошибки вылавливать?
Nik
44
Всем привет. Сейчас я изучаю erlang по книге Erlang and OTP in action. Дошел до главы где реализуется первый gen server на примере tcp rpc сервера. Меня очень сильно смутил ко...
Freezing Death
10
что за асемблер кста?
Shvabrikk Nya
19
Добрый день! Пробую отловить исключение EConvertError: function _TryTextToDouble(var DoubleVar: Extended; Text: String): Boolean; begin try DoubleVar := StrToFloat...
Kirill Filippenok
19
всем привет. реально ли понять чем в процессе занята память? delphi/linux, процесс свой
Handatros
12
Подскажите... Есть ли название у способа разработки кода, в котором: сперва пишут минимальную рабочую структуру: Напр. ввод, обработка, вывод, контроль. Потом эту структуру д...
Budemposmotret
6
В дизассемблере вижу, что строки пихают в регистры через lea, почему так, а не через mov?
Oleg
8
А где @Grinyaha уважаемый пропал?
Am Ambrion
14
Добрый вечер. Есть вопрос, а может и предложение. Был у меня диалог в другой группе о делфи и я задался вопросом: "А нельзя ли в делфи цвет //коментария и {комментария} сде...
Kraszx
24
Сделал краткий обзор магазина из статьи и заодно там же записал инструкцию по развёртыванию. https://www.youtube.com/watch?v=8-sE1vNk95Q (чё думаете по звуку? кое-что поменял...
Andrey K
17
Карта сайта