Потоки(Thread) — Программы(class) — Переменные

Стартовая страница Форумы Разработка и интеграция Потоки(Thread) — Программы(class) — Переменные

  • В этой теме 123 ответа, 4 участника, последнее обновление 2 года назад сделано manjey73.
Просмотр 15 сообщений - с 16 по 30 (из 124 всего)
  • Автор
    Записи
  • #33629
    Romiros
    Участник

    В модуле калькулятор идёт генерация исходного кода в рантайме из текста. Возможно подойдёт для Вашей задачи. Хороший образец для повторения, если не знаете как сделать. Но мне кажется правильнее было бы продумать наследование с расширением свойств и методов класса, учитывая что пользоваться будут не программисты.

    #33630
    manjey73
    Участник

    Ну и чем в данном случае генерация из текста будет отличаться от того же dynamic ? да еще и возни больше.

    Меня вполне устраивает мой вариант, но есть сложности с преобразованием типов.

    string myProg1 = «HeaterTest»; // тестовая, будет браться из конфига
    var typelist1 = Assembly.GetExecutingAssembly().GetExportedTypes().Where(x => x.Name == myProg1).FirstOrDefault(); // Получение списка только интересующего класса

    var type = Assembly.GetExecutingAssembly().GetType(typelist1.FullName);
    var instance = Activator.CreateInstance(type);

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

    if.. else надо лепить тут же. Типа
    if(instance.GetType() == «HeaterTest»)
    var prg = new HeaterTest();
    else if (и так далее)

    Как вынести отсюда if куда-нибудь в конец файла даже не представляю

    Как в коде создать обобщенную переменную и потом вызвать код для присвоения, который будет написан где-нибудь в конце?
    типа var prg;
    ProverType();
    и prg станет чем-то?

    • Ответ изменён 2 года, 1 месяц назад пользователем manjey73.
    #33632
    manjey73
    Участник

    Задница, if-ы тут не работают 🙁

    if (тип == «HeaterTest)
    HeaterTest prg = new HeaterTest();

    // Ошибка (активно) CS1023 Внедренный оператор не может быть объявлением или оператором с идентификатором

    Придется с dynamic ваять или есть еще какие способы?

    Неужели мне в начале делать кучу объявлений под каждый вариант программ ?

    #33633
    manjey73
    Участник

    Если под каждую прогу объявлять в начале HeaterTest heaterTest; и так далее, то так работает

    if (myProg1 == «HeaterTest»)
    heaterTest = instance as HeaterTest;

    var prg = heaterTest;

    #33634
    manjey73
    Участник

    Блин, и в конечном итоге это тоже работать не будет 🙁

    #33636
    manjey73
    Участник

    В общем остаемся на голой рефлексии. Оказалось что язык туповат в простой на первый взгляд вещи.

    Такой вопрос, не разобрался с этим как-то.
    Можно сделать пустой класс.
    class Prg { }
    И потом как-то на его основе делать свои программы
    class heater1()
    {
    набор неких переменных
    void Run(){ тут логика}
    }
    class heater2()
    {со всем своим}
    и так далее.

    И получить var prg = Activator.CreateInstance(type) as prg; например соответствующий heater2 если там его объект?

    #33637
    Romiros
    Участник

    Классы разных программ заранее известны? Если да, то создайте один абстрактный класс и наследуйтесь от него, расширяя список свойств и методов и при необходимости переопределяя родительские свойства и методы. Далее в рантайме создать этот абстрактный класс и проверять какой класс программы используется в конфиге и присваивать его абстрактному классу. Как-то так, если коротко.

    #33638
    manjey73
    Участник

    Вот если коротко, то облазил все и вся и не нашел решения.
    Вот что написано на одном из ресурсов при использовании Activator.CreateInstance(type)

    If you don’t know the actual type, then: not really, no. You would have to instead use one of:

    reflection
    implementing a well-known interface
    dynamic

    То есть либо напрямую через reflection, либо используя интерфейс, либо dynamic — последний при попытке запихнуть в Thread не работает.
    Если речь всего об одном классе, то
    var prg = Activator.CreateInstance(type) as heater1; работает прекрасно, prg становится heater1
    Но так как я не знаю, какой именно прилетит, то нельзя определить var никак. А то, что закинуто в if нельзя использовать дальше, так как VS не знает, что там будет.

    Классы программ известны только те, которые будут в отдельной dll (хочу так сделать) по умолчанию, далее могут добавляться, например heater3, cooling2 и так далее, и модуль о них будет знать только из шаблона например.

    #33639
    Romiros
    Участник

    Классы программ известны только те, которые будут в отдельной dll (хочу так сделать) по умолчанию, далее могут добавляться, например heater3, cooling2 и так далее, и модуль о них будет знать только из шаблона например.

    У Вас в шаблоне будет готовый c#? Типа:
    public class Heater3
    {
    public string name = «Heater3″;

    public void Print()
    {
    Console.WriteLine($»Имя: {name}»);
    }
    }
    Так что ли? И вы хотите добавить это в исходный код своего модуля?

    #33640
    manjey73
    Участник

    Нет, в модуле будет список программ, типа «Нагрев 1, Нагрев 2, Охлаждение 1» за счет словарей Lang а в модуле приведены к реальным именам классов типа Heater1, Heater2, Cooling1, который может быть дополнен списком из шаблона в котором уже надо будет писать реальные добавленные в DLL классы, типа «Heater3», «Cooling2» в зависимости от имени класса, который будет добавлен в dll

    Классы программ будут в отдельной dll типа по принципу ScadaComFunc
    И эта библиотека будет загружаться модулем и лежать рядом с основной библиотекой модуля.

    #33641
    Romiros
    Участник

    Т.е. классы под эти программы будут прописаны заранее в коде модуля? И просто по имени класса надо подставить необходимый,так что ли? Тогда используйте наследование. В RapidScada есть образцы. Ну или я не понимаю задачу.

    #33642
    manjey73
    Участник

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

    Там же вроде только в обратную сторону работает. У меня из общих переменных фактически только одна, типа terminate чтобы выйти из цикла и закрыть поток. Все остальное может быть разным.

    #33643
    Romiros
    Участник

    Возможно как-то так. Сможете сделать такие проверки в своем коде?
    A a;
    a = new B();

    //a.Method();//Тут получаем ошибку компилятора

    if (a is B)
    ((B)a).Method();//А тут уже нет

    Console.ReadLine();
    }
    }
    class A
    {

    }
    class B : A
    {
    public void Method()
    {
    Console.WriteLine(«In the Method»);
    }
    }

    #33644
    Romiros
    Участник

    А вообще, вспомнил, я уже кажется такое делал в одном драйвере. Там объект прилетал из REST API в виде json и далее в зависимости от типа преобразовывались в нужный класс. Могу завтра на работе поискать код.

    #33645
    manjey73
    Участник

    Поищи, интересно посмотреть, а то с классами я не очень понял, возможно ли это?
    Там загвоздка в том, что если я объявлю пустой класс, а потом буду выполнять проверку в if то далее я не вижу ничего, потому что родительский класс ни сном ни духом о списке переменных подчиненного класса. И VS соответственно не дает подсветки синтаксиса и прочего…

    Примерно как с dynamic — можно объявить как dinamic dyn и потом написать dyn.Run() — работать будет, но VS даже не предложит выбрать Run(), он просто должен там быть и все и если он там есть, то выполнится и не будет ошибки.

    То есть писать дальнейший код очень проблематично. Ну и dynamic не захотел в потоке работать, видимо компилятор так не может или еще что.

    з.ы. тут еще один момент — OnServiceStart и OnIteration их при этом всем еще надо совместить 🙂

Просмотр 15 сообщений - с 16 по 30 (из 124 всего)
  • Для ответа в этой теме необходимо авторизоваться.