Стартовая страница › Форумы › Разработка и интеграция › Потоки(Thread) — Программы(class) — Переменные
- В этой теме 123 ответа, 4 участника, последнее обновление 2 года назад сделано
manjey73.
-
АвторЗаписи
-
27.07.2024 в 10:16 #33629
Romiros
УчастникВ модуле калькулятор идёт генерация исходного кода в рантайме из текста. Возможно подойдёт для Вашей задачи. Хороший образец для повторения, если не знаете как сделать. Но мне кажется правильнее было бы продумать наследование с расширением свойств и методов класса, учитывая что пользоваться будут не программисты.
27.07.2024 в 12:45 #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.
27.07.2024 в 13:14 #33632
manjey73УчастникЗадница, if-ы тут не работают 🙁
if (тип == «HeaterTest)
HeaterTest prg = new HeaterTest();// Ошибка (активно) CS1023 Внедренный оператор не может быть объявлением или оператором с идентификатором
Придется с dynamic ваять или есть еще какие способы?
Неужели мне в начале делать кучу объявлений под каждый вариант программ ?
27.07.2024 в 13:18 #33633
manjey73УчастникЕсли под каждую прогу объявлять в начале HeaterTest heaterTest; и так далее, то так работает
if (myProg1 == «HeaterTest»)
heaterTest = instance as HeaterTest;var prg = heaterTest;
27.07.2024 в 13:31 #33634
manjey73УчастникБлин, и в конечном итоге это тоже работать не будет 🙁
28.07.2024 в 08:54 #33636
manjey73УчастникВ общем остаемся на голой рефлексии. Оказалось что язык туповат в простой на первый взгляд вещи.
Такой вопрос, не разобрался с этим как-то.
Можно сделать пустой класс.
class Prg { }
И потом как-то на его основе делать свои программы
class heater1()
{
набор неких переменных
void Run(){ тут логика}
}
class heater2()
{со всем своим}
и так далее.И получить var prg = Activator.CreateInstance(type) as prg; например соответствующий heater2 если там его объект?
28.07.2024 в 10:27 #33637Romiros
УчастникКлассы разных программ заранее известны? Если да, то создайте один абстрактный класс и наследуйтесь от него, расширяя список свойств и методов и при необходимости переопределяя родительские свойства и методы. Далее в рантайме создать этот абстрактный класс и проверять какой класс программы используется в конфиге и присваивать его абстрактному классу. Как-то так, если коротко.
28.07.2024 в 14:16 #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 и так далее, и модуль о них будет знать только из шаблона например.
28.07.2024 в 14:28 #33639Romiros
УчастникКлассы программ известны только те, которые будут в отдельной dll (хочу так сделать) по умолчанию, далее могут добавляться, например heater3, cooling2 и так далее, и модуль о них будет знать только из шаблона например.
У Вас в шаблоне будет готовый c#? Типа:
public class Heater3
{
public string name = «Heater3″;public void Print()
{
Console.WriteLine($»Имя: {name}»);
}
}
Так что ли? И вы хотите добавить это в исходный код своего модуля?28.07.2024 в 14:41 #33640
manjey73УчастникНет, в модуле будет список программ, типа «Нагрев 1, Нагрев 2, Охлаждение 1» за счет словарей Lang а в модуле приведены к реальным именам классов типа Heater1, Heater2, Cooling1, который может быть дополнен списком из шаблона в котором уже надо будет писать реальные добавленные в DLL классы, типа «Heater3», «Cooling2» в зависимости от имени класса, который будет добавлен в dll
Классы программ будут в отдельной dll типа по принципу ScadaComFunc
И эта библиотека будет загружаться модулем и лежать рядом с основной библиотекой модуля.28.07.2024 в 16:36 #33641Romiros
УчастникТ.е. классы под эти программы будут прописаны заранее в коде модуля? И просто по имени класса надо подставить необходимый,так что ли? Тогда используйте наследование. В RapidScada есть образцы. Ну или я не понимаю задачу.
28.07.2024 в 17:29 #33642
manjey73Участниктак классы полностью разные, как можно пустым родителем унаследовать все свойства и поля подчиненного?
Там же вроде только в обратную сторону работает. У меня из общих переменных фактически только одна, типа terminate чтобы выйти из цикла и закрыть поток. Все остальное может быть разным.
28.07.2024 в 18:32 #33643Romiros
УчастникВозможно как-то так. Сможете сделать такие проверки в своем коде?
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»);
}
}28.07.2024 в 18:39 #33644Romiros
УчастникА вообще, вспомнил, я уже кажется такое делал в одном драйвере. Там объект прилетал из REST API в виде json и далее в зависимости от типа преобразовывались в нужный класс. Могу завтра на работе поискать код.
29.07.2024 в 08:40 #33645
manjey73УчастникПоищи, интересно посмотреть, а то с классами я не очень понял, возможно ли это?
Там загвоздка в том, что если я объявлю пустой класс, а потом буду выполнять проверку в if то далее я не вижу ничего, потому что родительский класс ни сном ни духом о списке переменных подчиненного класса. И VS соответственно не дает подсветки синтаксиса и прочего…Примерно как с dynamic — можно объявить как dinamic dyn и потом написать dyn.Run() — работать будет, но VS даже не предложит выбрать Run(), он просто должен там быть и все и если он там есть, то выполнится и не будет ошибки.
То есть писать дальнейший код очень проблематично. Ну и dynamic не захотел в потоке работать, видимо компилятор так не может или еще что.
з.ы. тут еще один момент — OnServiceStart и OnIteration их при этом всем еще надо совместить 🙂
-
Ответ изменён 2 года, 1 месяц назад пользователем
-
АвторЗаписи
- Для ответа в этой теме необходимо авторизоваться.