Приветствуем на Форум Херсона. Форум Херсонской молодежи.. На данный момент Вы находитесь на форуме как Гость и имеете очень ограниченные возможности и права. Что бы писать или отвечать в темах, загружать картинки, файлы на форуме Вам нужно зарегистрироваться, что совершенно бесплатно. Регистрация очень быстрая, не откладывайте эту процедуру! Если возникнут проблемы с регистрацией напишите нам. |
|
Программирование Все вопросы по написанию программ |
|
Опции темы |
29.10.2009, 00:22 | #1 (Ссылка на пост) | ||||||||
Задержался
Пол:
Благодарил(а): 12
Благодарили 104 раз в 19 постах
Галерея:
0
Вес репутации: 17
|
Головоломка для C#
Есть головоломка которую пытаюсь долго и нужно решить на C#
По логике все было понятно а вот в реальности работа компилятора , да и сами законы C# сделали обратное. Задача в том что нужен синтаксис вызова методов определенной структуры: PHP код:
через проперти все вроде реально, и все работает , за искючением ситуации, что test1 получает test2 и даже test2() в статичном виде, я так понимаю на этапе компиляции. А вот нужно чтобы вызов был динамичный. Т.е. test1() получал , какбы не значение а сылку на метод и при обращении ее запускал по типу eval(). Головоломка пока оказалась не позубам, перепробовла тучи вариантов. Вот ниже пример кода для теста в котором обращение к test2 идет 2 раза на цикл, но реально консоль показывает что в каждом цикле test1 значение test2 одинаковое PHP код:
|
||||||||
|
29.10.2009, 11:33 | #2 (Ссылка на пост) | ||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Привет, Здесь проблема более концептуальная.
Дело в том что все типы в .Net-е деляется на Value и Reference типы. Int (как и многие простые типы) относится к Value типами. А Value тип при передаче параметром копирует своё значение. И в данном случае он один раз вычисляется при каждом вызове Test2, и результат уже идет дальше в вызов без привязки к свойству. Можно сделать так через анонимный метод: PHP код:
Хотя в данном случае Reference тип вел бы себя так же наверно. Проблема была в том что передавалась не ссылка на геттер свойсвта Test2, а само полученное значение этого свойсвта. PhoeniXX добавил 29.10.2009 в 12:40 Можно еще сделать так: PHP код:
Или можно просто напрямую в методе Test1 обращятся к свойсвту Test2 PhoeniXX добавил 29.10.2009 в 19:08 А вот еще более корректный ООП вариант: PHP код:
Последний раз редактировалось PhoeniXX, 29.10.2009 в 18:08. Причина: Добавлено сообщение |
||||||||
|
30.10.2009, 17:45 | #3 (Ссылка на пост) | |||||||||
Забанен вапще
Пол:
Благодарил(а): 57
Благодарили 28 раз в 15 постах
Галерея:
0
Вес репутации: 0
|
Цитата:
|
|||||||||
|
05.11.2009, 02:01 | #4 (Ссылка на пост) | |||||||||
Задержался
Пол:
Благодарил(а): 12
Благодарили 104 раз в 19 постах
Галерея:
0
Вес репутации: 17
|
Цитата:
тут больше LINQ подходит для решения задачи аналогичной SQL где таже AVG() может принимать и колонку и выражение и т.д. Но вот немогу осилить это таким образом чтобы вызов был в примитивах test1(test2+test3/3,2)*test1(test3+test2/3, 2) для примера. Т.е. попытка пойти логикой Плагина. Вводится код понятный юзверу, который вставляется в темплейт и генерится как плагин и отрабатывает. SQL вроде как является интерпритатором, но сама мысль парсить на разделители и обрабатывать просто ужасает. |
|||||||||
|
05.11.2009, 07:02 | #5 (Ссылка на пост) | |||||||||
Забанен вапще
Пол:
Благодарил(а): 57
Благодарили 28 раз в 15 постах
Галерея:
0
Вес репутации: 0
|
Цитата:
|
|||||||||
|
05.11.2009, 18:41 | #6 (Ссылка на пост) | ||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Так же существует ANTLR http://www.antlr.org/. Он нужен для создания парсера на основе некой грамматики. В принципе он довольно неплох, и позволяет уйти от изобретения велосипеда.
Ему нужно сделать грамматику операций, и он потом на её основе сделает парсер по этой грамматике. Парсер он может делать на разных языках. Помню там был C#, Java, и C++ вроде. PhoeniXX добавил 05.11.2009 в 19:45 В самом ANTLR-е есть много примеров грамматик. Так же есть пример простого мат калькулятора. PhoeniXX добавил 05.11.2009 в 19:53 Вот к примеру sample-овая грамматика для простейшего калькулятора. Действия +, *, (,). По такому принципу вполне доделывается остальные нужные дейсвтия. Данный пример для Java, но отличий, в данном случае, почти никаких нет. Грамматика: PHP код:
Последний раз редактировалось PhoeniXX, 05.11.2009 в 18:53. Причина: Добавлено сообщение |
||||||||
|
09.11.2009, 16:54 | #7 (Ссылка на пост) | ||||||||
Задержался
Пол:
Благодарил(а): 12
Благодарили 104 раз в 19 постах
Галерея:
0
Вес репутации: 17
|
Пытался хитрить с MethodInfo и снова встрял чуток изменив задачку
Код:
using System; using System.Reflection; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } public int count = 0; public int test1(MethodInfo val, int exp) { for (int i = 0; i < exp; i++) { Console.Write((int)val.Invoke(this,null)); } return 1; } public int test2() { count += 1; return count; } public int test3(MethodInfo val, int exp) { for (int i = 0; i < exp; i++) { Console.Write("|"+(int)val.Invoke(this, null)+"|"); } return 1; } private void button1_Click(object sender, EventArgs e) { MethodInfo test2 = GetType().GetMethod("test2"); MethodInfo test3 = GetType().GetMethod("test3"); for (var i = 0; i < 5; i++) { test1(test2, 2); test1(test3(test2,2), 2); } } } } |
||||||||
|
09.11.2009, 17:16 | #8 (Ссылка на пост) | ||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Проблема в том, что в данном случае test3 - это тип MethodInfo, то есть просто набор мета информации о методе. И его нельзя так употреблять.
Можно либо вызвать его: test1(test3.Invoke(this, new object[]{test2,2}), 2); Либо передать так же, как ссылку на метод test3: test1(test3,2); В первом случае - будет ошибка, так как мы вызываем метод, и передаем его результат как первый параметр метода test1. А первый параметр там указан как MethodInfo, а результат test3 будет типа int. Если же нужно передать ссылку на метод, и его параметры, то нужно передавать их поотдельности. Типа: test1(test3,test2,2,2) Но данное решение не подходит сдесь так как оно сильно захардкоджено PhoeniXX добавил 09.11.2009 в 18:51 Вот пример кода: PHP код:
12 |3||4|1|5||6|1 Для вложенного второго вызове test1 идет такая цепочка вызово: test1 started test3 started test2 started test2 ended test2 started test2 ended test3 ended test3 started test2 started test2 ended test2 started test2 ended test3 ended test1 ended Но опять же, если это должно парситься из некой строки - лучше всего заюзать Antlr. Так как, мой вариант, отдаёт сильно корявостью. Последний раз редактировалось PhoeniXX, 09.11.2009 в 17:51. Причина: Добавлено сообщение |
||||||||
|
09.11.2009, 19:04 | #9 (Ссылка на пост) | ||||||||
Местные мы
Пол:
Благодарил(а): 457
Благодарили 620 раз в 179 постах
Галерея:
0
Вес репутации: 23
|
Ээ а можно спросить, я просто совсем не понял условие, что собственно требуется.
То есть, есть некая запись например в txt файле: test1(test2+test3/3,2)*test1(test3+test2/3, 2) и нужно её распарсить и выполнить это дело в коде (test1 - метод, остальные - проперти). Так? (или test1 это тоже типа как проперти и инициализируется тем что в скобках) |
||||||||
|
09.11.2009, 23:18 | #10 (Ссылка на пост) | |||||||||
Задержался
Пол:
Благодарил(а): 12
Благодарили 104 раз в 19 постах
Галерея:
0
Вес репутации: 17
|
Цитата:
парсить тяжко, даже нехочется начинать. малоли что юзверу может прийти в голову , так напишет что бошку снесет. плавали знаем. вот и думал более простым способом. Генерить dll ввиду плагина, вставлять строчку кода и запускать. Все работает красиво НО!!! у всех методов есть параметр test1(int val) к примеру, что означает прием variable и вызов test(test2() * 0.5) вроде и выполнит но ввиде статики. Т.е. если к примеру внутри test1 будет цикл со смещением рекорда и вызов test2() каждый раз то test2 всегд абудет единый как статичный на момент передачи его как параметра. что не есть хорошо. test1(test2(),2); test1(int m,2){ print m() next record print m() } |
|||||||||
|
10.11.2009, 10:46 | #11 (Ссылка на пост) | ||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Если есть некие правила ввода и пользователь их не соблюдает, это проблема пользователя. Как по мне, достаточно отображения окошка с ошибкой что некорректный синтаксис - ошибка тут.
Честно говоря, я не улавливаю практического применения данной головоломки. Если там есть определённый синтаксис, то его можно, опять же, описать грамматикой Antlr-а, которую будет потом намного проще изменять и дополнять, чем делать что-то своё. Хотя опять же зависит от задачи. |
||||||||
|
10.11.2009, 13:15 | #12 (Ссылка на пост) | |||||||||
Забанен вапще
Пол:
Благодарил(а): 57
Благодарили 28 раз в 15 постах
Галерея:
0
Вес репутации: 0
|
Цитата:
Я нашел реализованную уже идею. Все гораздо проще. На счет разборки синтаксиса. Тут парсер синтаксиса подойдет. Почему, да по тому что ещё идет передача JS интерпретатору этих функций и нужно все разбирать как дерево решений на атомарные части. |
|||||||||
|
10.11.2009, 18:03 | #13 (Ссылка на пост) |
Stars align
Пол:
|
|
|
10.11.2009, 18:39 | #14 (Ссылка на пост) | ||||||||
Задержался
Пол:
Благодарил(а): 12
Благодарили 104 раз в 19 постах
Галерея:
0
Вес репутации: 17
|
нееее, нафиг форекс ... это незадача какаято 100 пудово. Просто пытаюсь отдельными головоломками решить и прощупать разные куски и моменты общей задачи. Так вот с плагином бился отдельно, решил но осталься баг в том что подгрузив dll уже перекомпилить нельзя, так-как особождатся нехочется и dll находится в lock режиме как заюзанная.
С это задачей на вложения, выдерал из разных примеров куски и взял самый простой пример но который как раз выявляет глюк или ограничение C# . Помогает изучить C# ковыряясь в разных кусках кода и разных задачах. пригодится на будущее. уменя уже тучи варианто вразных подходо вк разным задачам накопилось а вот юзать пока некуда , может када пригодится кстати решилось все небольшими изминениями, через делигат, но вот код теперь хоть и понятный но для ювзера нереальный, явно нужно или риплейсить или снова заниматься парсингом :( : Код:
using System; using System.Reflection; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } public int count = 0; public delegate decimal Action(); public int test1(Action action, int exp) { for (int i = 0; i < exp; i++) { Console.Write(action()); } return 1; } public int test2() { count += 1; return count; } public int test3(Action action, int exp) { for (int i = 0; i < exp; i++) { Console.Write(action()); } return 1; } private void button1_Click(object sender, EventArgs e) { for (var i = 0; i < 5; i++) { test1( delegate{ return test3( delegate{ return test2();} , 2 );} , 2); } } } } |
||||||||
|
10.11.2009, 19:01 | #15 (Ссылка на пост) | |||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Цитата:
А в .Net-е можно вполне подгружать dll сборку, потом выгружать её, в рантайме из текста билдить новую dll, заменять всё ту же dll сборку, и запускать её. А еще есть IronPython, который так же можно загружать и выполнять в рантайме. Последний раз редактировалось PhoeniXX, 10.11.2009 в 19:05. |
|||||||||
|
Сказали Спасибо пользователю PhoeniXX за этот пост: | *Ihor* (10.11.2009) |
10.11.2009, 20:11 | #16 (Ссылка на пост) | |||||||||
Задержался
Пол:
Благодарил(а): 12
Благодарили 104 раз в 19 постах
Галерея:
0
Вес репутации: 17
|
Цитата:
генерация: Код:
rtfCode = "................................";
CSharpCodeProvider csp = new CSharpCodeProvider();
ICodeCompiler cc = csp.CreateCompiler();
CompilerParameters cp = new CompilerParameters();
cp.OutputAssembly = Application.StartupPath + "\\testScript.dll";
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("mscorlib.dll");
cp.ReferencedAssemblies.Add("test.exe");
cp.WarningLevel = 3;
cp.CompilerOptions = "/target:library /optimize";
cp.GenerateExecutable = false;
cp.GenerateInMemory = false;
System.CodeDom.Compiler.TempFileCollection tfc = new TempFileCollection(Application.StartupPath, false);
CompilerResults cr = new CompilerResults(tfc);
cr = cc.CompileAssemblyFromSource(cp, rtfCode);
Код:
Assembly assembly; Type typeofClass; assembly = Assembly.LoadFrom("testScript.dll"); typeofClass = assembly.GetType("test.Script", true, false); Command mathClass = (Command)Activator.CreateInstance(typeofClass); mathClass.Execute(); *Ihor* добавил 10.11.2009 в 21:16 какие есть идеи по поводу превращения test1(test3(test2(),2),2); в test1( delegate{ return test3( delegate{ return test2();} , 2 );} , 2); обьявить делигаты в самом начале общие на все фозвожные методы test3 = new delegate test3(); врядли заработает так-как в каждом варианте исполнение будут свои варианты типа test3(...,2) , т.е. нужно создавать делигаты на каждый реальный вариант. остается более реальный это регулярка. но вот те так просто заменить test3( на delegate {return test3( ... ведь конец ) нужный найти нетак просто из тучи скобок. Последний раз редактировалось *Ihor*, 10.11.2009 в 20:16. Причина: Добавлено сообщение |
|||||||||
|
10.11.2009, 21:06 | #17 (Ссылка на пост) | ||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Здесь есть момент, сам .Net когда загружает сборку - он её грузит в AppDomain, и выгрузит он её уже не может.
Есть способ загрузки только мета информации - тогда её можно выгрузить. Самый простой способ запустить сборку, а потом её выгрузить с разлачиванием файла и возможносью удаления файла сборки - через другой AppDomain. Смысл просто - создаётся новый AppDomain, ему через CrossAppDomain метод говорится, какую сборку он должен открыть и что с ней делать. Потом в конце - он уничтожается, и освобождает вместе с собой хендл на файл сборки. После чего dll файл можно удалять. Но здесь есть большое но - два домена не должны быть связаны существующими объектами, тогда не получится её удалить. Если нужно сделать взаимодействие - можно вполне воспользоватся Remoting-ом либо WCF(в зависимости от версии .Net-а). Зато есть большой плюс в плане секьюрити - независимость доменов и не возможность менять Reflection-ом рантаймовые объекты в основном домене. И так же если упадёт второй домен - то первый будет жить. Насчет test3 - я вообще не понимаю смысл этого, и практическое применение, и соответсвенно не могу понять что нужно сделать. Если там есть синтаксим - есть Antlr с грамматиками. |
||||||||
|
Сказали Спасибо пользователю PhoeniXX за этот пост: | *Ihor* (10.11.2009) |
10.11.2009, 21:21 | #18 (Ссылка на пост) | ||||||||
Задержался
Пол:
Благодарил(а): 12
Благодарили 104 раз в 19 постах
Галерея:
0
Вес репутации: 17
|
c AppDomain я пробовал. после удаления и освобождения, dll всеодно была занята. просто тест, загрузил dll освободил все объекты, тут же в тотале пытался удалть dll и нифига. Искал в инете, как заметил - обсуждений вокруг этого много, т.е. гемор еще тот видимо.
отдельные куски чисто для теста или обкатки и особого смысла обычно ненесут. сталкиваеся с проблемой, отделяешь ее и начинаешь гонять и перекручивать, решая конкретный кусок необращая внимания на все остальное ... в данном случае я уже решил как я думаю траблу со статичными параметрами. терь вот отложил и пытаюсь придумать более легкий способ превращения одного текста в другой. узать Antlr нехочется, стараюсь всегда обходится чисто кодом без юзанья всего подряд. да и в голову уже нелезит этот Antlr, мне и так хватает того что у меня уже в бошке (юзаю одновременно около 9 языков).. вот еще пытался F# осилить но уже нелезит. а Antlr почти тоже самое, уж лучше тогда F# и покдлючить в C#. замена test3(...,2) на delegate{ return test3(...,2);} вполне решается regexp тока это не так легко, регулярка та еще зараза. |
||||||||
|
10.11.2009, 22:30 | #19 (Ссылка на пост) | ||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Не согласен.
Antlr != F# + C#. Это языки разных предназначений. Сам по себе Antlr не привязывается к конкретному языку. Но мне то что, моё дело посоветовать. К слову о 9 языках, средний Asp.Net веб программер юзает - Html, JavaScript, Asp.Net разметку, C#, TSQL. Уже 5 языков(Ну может 4, если не брать в расчет Asp.Net разметку). 9 языков - не говорит о сложности проекта. Насчет AppDomain - этот способ работает, так как я его использовал. Если dll-ка лочится, значит она загружается в основном домене. PhoeniXX добавил 11.11.2009 в 00:03 Имхо, есть такая фраза - не стоит делать фичу ради фичи. Поэтому использовать F# чисто чтоб было, и не использовать весь его потенциал - как минимум нет смысла. F# функциональный язык со всеми вытекающими, а Antlr - по сути генератор парсера на основе LL граматики. И связи толком у них нет. Последний раз редактировалось PhoeniXX, 10.11.2009 в 23:04. Причина: Добавлено сообщение |
||||||||
|
Сказали Спасибо пользователю PhoeniXX за этот пост: | pingwinator (10.11.2009) |
11.11.2009, 01:57 | #20 (Ссылка на пост) | ||||||||
Задержался
Пол:
Благодарил(а): 12
Благодарили 104 раз в 19 постах
Галерея:
0
Вес репутации: 17
|
неее я не юзаю 9 языков в одном проэкте я шо самогубец ? я просто каждый день работаю с разными проэктами причем в один день могу делать разные проэкты на разных платформах, естевстенно и языки задач разные, в голове уже полная каша, как говорится места на винте уже под завязку, потому F# с первого захода неосилил, хотя их конференции и семинары преподнесли его как чтото вкусное, но то все для аналитиков с WTC или математиков для forex, узконаправленное.
Antlr я смотрел, как интерпритатор он менее удобен. Я решил проблему чисто делигатами причем не потеряв в производительности по сравнению обработкой через парсинг. Чтобы решить эту головоломку с параметрами ввид ссылок с помощью Antlr или других вариантов , это тоже самое что самому разложить все вложения на отдельное решение под задачь через временные масивы, а это потеря производительности, C# сам лучше это сделает управляя памятью в среде framework. Интерпритаторы хороши для мелких задач, а вод для обработки обьема или отчетов уж лучше доверить SQL и процедурам на стороне DBServer. Тотже forex который упомянули, как мне кажеться лучше обработать базой а не парсерами самодельными. |
||||||||
|
11.11.2009, 11:23 | #21 (Ссылка на пост) | |||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Цитата:
К слову, о хорошести - на ANTLR-е уже есть написанные граматики для интерпретации HTML,SQL, Oracle, Java 1.5 and 1.6,Pascal, C/C++, C#. Как по мне это не тянет на мелкие задачи. Любой интерпретатор хорошо, так как он позволяет не изобретать свой велосипед. |
|||||||||
|
11.11.2009, 21:36 | #22 (Ссылка на пост) | |||||||||
Задержался
Пол:
Благодарил(а): 12
Благодарили 104 раз в 19 постах
Галерея:
0
Вес репутации: 17
|
Цитата:
Сейчас уже никто так неработает как раньше. Ранее я всегда брал самый старый и тормознутый комп, запускал задачи в сумашедшие циклы и менял код пока неполучу макс. производительность. теперь же все привыкли что ресурсы доступные всем, и никто несчитается нетолько с секундами но и поболее. Теже веб страницы, все привыкли что инет уже почти у всех скоростной, и несмотрят что сжираются миниму 3-5 сек тупо не на трафик а на речеки браузерами ресурсов. Так и в программировании, постоянно сижу и переделываю чужие куски кода. Недавно вообще был в шоке када попал в руки код в 15 строк который на 2х кросс таблицах тупо ложил сервак на полторы мунуты форами, 250 x 4500 записях. после переделки получил 2-3 сек. Вот потому и сижу ковыряю, кручу, мудрю, чтоб быть увереным что лучше варианта нету |
|||||||||
|
11.11.2009, 22:03 | #23 (Ссылка на пост) | ||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
напомнило фразу - "хабр уже не тот"
|
||||||||
|