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 ответов

16 просмотров

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

в чем именно проблема? зачем делать метод 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 Уже всё есть и никакого билда не надо

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

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

30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Всем привет! Имеется функция: function IsValidChar(ch: UTF8Char): Boolean; var i: Integer; ValidChars: AnsiString; begin ValidChars := 'abcdefghijklmnopqrstuvwxyzABCDE...
Евгений
44
Карта сайта