Форум Херсона. Форум Херсонской молодежи, флейм, фотографии Херсона, политика в Херсоне, сетевой форум, сети Херсона


Приветствуем на Форум Херсона. Форум Херсонской молодежи..

На данный момент Вы находитесь на форуме как Гость и имеете очень ограниченные возможности и права. Что бы писать или отвечать в темах, загружать картинки, файлы на форуме Вам нужно зарегистрироваться, что совершенно бесплатно. Регистрация очень быстрая, не откладывайте эту процедуру!

Если возникнут проблемы с регистрацией напишите нам.

Галерея форума Блоги пользователей Список банов
Вернуться   Форум Херсона. Форум Херсонской молодежи. > > >
Регистрация СправкаСтатистика Пользователи Календарь Сообщения за день

Программирование Все вопросы по написанию программ

Тема: Головоломка для C# Ответить в теме
Ваше имя пользователя: Для входа нажмите здесь
Проверка вопроса системы антиспама "NoSpam!"
Столиця Русі
Image Verification
Пожалуйста, введите шесть букв и/или цифр, которые изображены на картинке.

Заголовок:
  
Сообщение:
Иконки для сообщения
Вы можете выбрать иконку, характеризующую сообщение:
 

Дополнительные опции
Другое

Просмотр темы (Новые вначале)
11.11.2009 22:03
PhoeniXX напомнило фразу - "хабр уже не тот"
11.11.2009 21:36
*Ihor*
Цитата:
Сообщение от PhoeniXX Посмотреть сообщение
Как я уже говорил, Antlr только генератор, и в итоге он генерирует C# код, Runtime Framework тот же.
а вот тут и есть загвоздка. чтобы решить подобную задачу нужно разложить на подзадачи через временные масивы. т.е. вревратить код одной строки в большее кол-во строк кода. Другого решения нету этой задачи. А вот чтоб ырешить быстро и проще и искалось нестандартное решение. Как раз через делигаты в последнем варианте все решилось одной строкой на уровне исполняемого кода и за один проход. Я понимаю что ты видишь преймущества Antlr , но я также вижу и минусы его. Любой другой программер, даже без Antlr решил бы эту головоломку, сделав СТАНДАРТНое решение, разделить на подзадачи, выполнить отдельно каждый кусок, поместить в масив, потом другой кусок и т.д. Вот такие подходы и жрут обьем и память, а все потому что так проще, взять распарсить и непарить мозги. Яже потратил в разы больше времени но получил решение которое избавило от парсинга и выдало максимальную скорость, от чего и получил большое удовольствие
Сейчас уже никто так неработает как раньше. Ранее я всегда брал самый старый и тормознутый комп, запускал задачи в сумашедшие циклы и менял код пока неполучу макс. производительность. теперь же все привыкли что ресурсы доступные всем, и никто несчитается нетолько с секундами но и поболее. Теже веб страницы, все привыкли что инет уже почти у всех скоростной, и несмотрят что сжираются миниму 3-5 сек тупо не на трафик а на речеки браузерами ресурсов. Так и в программировании, постоянно сижу и переделываю чужие куски кода. Недавно вообще был в шоке када попал в руки код в 15 строк который на 2х кросс таблицах тупо ложил сервак на полторы мунуты форами, 250 x 4500 записях. после переделки получил 2-3 сек.
Вот потому и сижу ковыряю, кручу, мудрю, чтоб быть увереным что лучше варианта нету
11.11.2009 11:23
PhoeniXX
Цитата:
Сообщение от *Ihor* Посмотреть сообщение
Чтобы решить эту головоломку с параметрами ввид ссылок с помощью Antlr или других вариантов , это тоже самое что самому разложить все вложения на отдельное решение под задачь через временные масивы, а это потеря производительности, C# сам лучше это сделает управляя памятью в среде framework. Интерпритаторы хороши для мелких задач, а вод для обработки обьема или отчетов уж лучше доверить SQL и процедурам на стороне DBServer. Тотже forex который упомянули, как мне кажеться лучше обработать базой а не парсерами самодельными.
Как я уже говорил, Antlr только генератор, и в итоге он генерирует C# код, Runtime Framework тот же.
К слову, о хорошести - на ANTLR-е уже есть написанные граматики для интерпретации HTML,SQL, Oracle, Java 1.5 and 1.6,Pascal, C/C++, C#. Как по мне это не тянет на мелкие задачи.
Любой интерпретатор хорошо, так как он позволяет не изобретать свой велосипед.
11.11.2009 01:57
*Ihor* неее я не юзаю 9 языков в одном проэкте я шо самогубец ? я просто каждый день работаю с разными проэктами причем в один день могу делать разные проэкты на разных платформах, естевстенно и языки задач разные, в голове уже полная каша, как говорится места на винте уже под завязку, потому F# с первого захода неосилил, хотя их конференции и семинары преподнесли его как чтото вкусное, но то все для аналитиков с WTC или математиков для forex, узконаправленное.

Antlr я смотрел, как интерпритатор он менее удобен. Я решил проблему чисто делигатами причем не потеряв в производительности по сравнению обработкой через парсинг. Чтобы решить эту головоломку с параметрами ввид ссылок с помощью Antlr или других вариантов , это тоже самое что самому разложить все вложения на отдельное решение под задачь через временные масивы, а это потеря производительности, C# сам лучше это сделает управляя памятью в среде framework. Интерпритаторы хороши для мелких задач, а вод для обработки обьема или отчетов уж лучше доверить SQL и процедурам на стороне DBServer. Тотже forex который упомянули, как мне кажеться лучше обработать базой а не парсерами самодельными.
10.11.2009 22:30
PhoeniXX Не согласен.
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 граматики. И связи толком у них нет.
10.11.2009 21:21
*Ihor* c AppDomain я пробовал. после удаления и освобождения, dll всеодно была занята. просто тест, загрузил dll освободил все объекты, тут же в тотале пытался удалть dll и нифига. Искал в инете, как заметил - обсуждений вокруг этого много, т.е. гемор еще тот видимо.

отдельные куски чисто для теста или обкатки и особого смысла обычно ненесут. сталкиваеся с проблемой, отделяешь ее и начинаешь гонять и перекручивать, решая конкретный кусок необращая внимания на все остальное ... в данном случае я уже решил как я думаю траблу со статичными параметрами. терь вот отложил и пытаюсь придумать более легкий способ превращения одного текста в другой.
узать Antlr нехочется, стараюсь всегда обходится чисто кодом без юзанья всего подряд. да и в голову уже нелезит этот Antlr, мне и так хватает того что у меня уже в бошке (юзаю одновременно около 9 языков).. вот еще пытался F# осилить но уже нелезит. а Antlr почти тоже самое, уж лучше тогда F# и покдлючить в C#.

замена test3(...,2) на delegate{ return test3(...,2);} вполне решается regexp тока это не так легко, регулярка та еще зараза.
10.11.2009 21:06
PhoeniXX Здесь есть момент, сам .Net когда загружает сборку - он её грузит в AppDomain, и выгрузит он её уже не может.
Есть способ загрузки только мета информации - тогда её можно выгрузить.

Самый простой способ запустить сборку, а потом её выгрузить с разлачиванием файла и возможносью удаления файла сборки - через другой AppDomain. Смысл просто - создаётся новый AppDomain, ему через CrossAppDomain метод говорится, какую сборку он должен открыть и что с ней делать. Потом в конце - он уничтожается, и освобождает вместе с собой хендл на файл сборки. После чего dll файл можно удалять. Но здесь есть большое но - два домена не должны быть связаны существующими объектами, тогда не получится её удалить. Если нужно сделать взаимодействие - можно вполне воспользоватся Remoting-ом либо WCF(в зависимости от версии .Net-а). Зато есть большой плюс в плане секьюрити - независимость доменов и не возможность менять Reflection-ом рантаймовые объекты в основном домене. И так же если упадёт второй домен - то первый будет жить.

Насчет test3 - я вообще не понимаю смысл этого, и практическое применение, и соответсвенно не могу понять что нужно сделать.
Если там есть синтаксим - есть Antlr с грамматиками.
10.11.2009 20:11
*Ihor*
Цитата:
Сообщение от PhoeniXX Посмотреть сообщение
А в .Net-е можно вполне подгружать dll сборку, потом выгружать её, в рантайме из текста билдить новую dll, заменять всё ту же dll сборку, и запускать её. А еще есть IronPython, который так же можно загружать и выполнять в рантайме.
тем модходом что я сделал освободить неполучилось пока.

генерация:
Код:
            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( ... ведь конец ) нужный найти нетак просто из тучи скобок.
10.11.2009 19:01
PhoeniXX
Цитата:
Сообщение от *Ihor* Посмотреть сообщение
Так вот с плагином бился отдельно, решил но осталься баг в том что подгрузив dll уже перекомпилить нельзя, так-как особождатся нехочется и dll находится в lock режиме как заюзанная.
С это задачей на вложения, выдерал из разных примеров куски и взял самый простой пример но который как раз выявляет глюк или ограничение C# .
На самом деле это не совсем ограничение. Это постановка задачи такая. Я думаю в С++, была бы аналогичная проблема, так как передавать пришлось бы указатель на функцию. И проблема с параметром была бы такой же.

А в .Net-е можно вполне подгружать dll сборку, потом выгружать её, в рантайме из текста билдить новую dll, заменять всё ту же dll сборку, и запускать её. А еще есть IronPython, который так же можно загружать и выполнять в рантайме.
10.11.2009 18:39
*Ihor* нееее, нафиг форекс ... это незадача какаято 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 18:03
Gravy
Цитата:
Сообщение от Honer Посмотреть сообщение
Создаем портал для форексов, даем гарантии, собираем деньги с пользователей системы и уходим. Создаем новый портал.
рассказать что дальше будет или сам догадаешся?
10.11.2009 13:15
Honer
Цитата:
Сообщение от PhoeniXX Посмотреть сообщение
Если есть некие правила ввода и пользователь их не соблюдает, это проблема пользователя. Как по мне, достаточно отображения окошка с ошибкой что некорректный синтаксис - ошибка тут.
Честно говоря, я не улавливаю практического применения данной головоломки.
Если там есть определённый синтаксис, то его можно, опять же, описать грамматикой Antlr-а, которую будет потом намного проще изменять и дополнять, чем делать что-то своё. Хотя опять же зависит от задачи.
Да, согласен. Но самое печальное то, что исполнители не видят всей задачи. Просто заказчик переопределяет часто исполнителей для сохранения конфиденциальности. Задача проекта дается частями и поэтому никто не знает каков должен быть результат проекта. А вообще проект вода для лохотрона игроков Форекс. Система. Создаем портал для форексов, даем гарантии, собираем деньги с пользователей системы и уходим. Создаем новый портал. Я уже как 2 месяца работаю с фин аналитиками и не вижу в том что есть 100% смысла. Есть MT4 и MQL. Там и тестеры стратегий, и анализаторы, и статистики. Тренд система со своим синтаксисом.
Я нашел реализованную уже идею. Все гораздо проще.
На счет разборки синтаксиса. Тут парсер синтаксиса подойдет.
Почему, да по тому что ещё идет передача JS интерпретатору этих функций и нужно все разбирать как дерево решений на атомарные части.
10.11.2009 10:46
PhoeniXX Если есть некие правила ввода и пользователь их не соблюдает, это проблема пользователя. Как по мне, достаточно отображения окошка с ошибкой что некорректный синтаксис - ошибка тут.
Честно говоря, я не улавливаю практического применения данной головоломки.
Если там есть определённый синтаксис, то его можно, опять же, описать грамматикой Antlr-а, которую будет потом намного проще изменять и дополнять, чем делать что-то своё. Хотя опять же зависит от задачи.
09.11.2009 23:18
*Ihor*
Цитата:
Сообщение от Marchello Посмотреть сообщение
Ээ а можно спросить, я просто совсем не понял условие, что собственно требуется.
То есть, есть некая запись например в txt файле:
test1(test2+test3/3,2)*test1(test3+test2/3, 2)

и нужно её распарсить и выполнить это дело в коде (test1 - метод, остальные - проперти). Так?
(или test1 это тоже типа как проперти и инициализируется тем что в скобках)
можно все методами просто вместо test2() проще писать test2 без скобок но то чисто делигаты и неособо важно.
парсить тяжко, даже нехочется начинать. малоли что юзверу может прийти в голову , так напишет что бошку снесет. плавали знаем.
вот и думал более простым способом. Генерить 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()
}
09.11.2009 19:04
Marchello Ээ а можно спросить, я просто совсем не понял условие, что собственно требуется.
То есть, есть некая запись например в txt файле:
test1(test2+test3/3,2)*test1(test3+test2/3, 2)

и нужно её распарсить и выполнить это дело в коде (test1 - метод, остальные - проперти). Так?
(или test1 это тоже типа как проперти и инициализируется тем что в скобках)
09.11.2009 17:16
PhoeniXX Проблема в том, что в данном случае 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 код:
  class Program
    
{
        static 
void Main(string[] args)
        {
            new 
Program().button1_Click(nullEventArgs.Empty);
        }

        public 
int count 0;
        public 
int test1(MethodHolder valint exp)
        {
            
Debug.WriteLine("test1 started");
            for (
int i 0expi++)
            {
                
Console.Write((int)val.Invoke());
            }
            
Debug.WriteLine("test1 ended");
            return 
1;
        }
        public 
int test2()
        {
            
Debug.WriteLine("test2 started");
            
count += 1;
            
Debug.WriteLine("test2 ended");
            return 
count;
        }
        public 
int test3(MethodHolder valint exp)
        {
            
Debug.WriteLine("test3 started");
            for (
int i 0expi++)
            {
                
Console.Write("|" + (int)val.Invoke() + "|");
            }
            
Debug.WriteLine("test3 ended");
            return 
1;
        }
        private 
void button1_Click(object senderEventArgs e)
        {
            
MethodInfo test2 GetType().GetMethod("test2");
            
MethodInfo test3 GetType().GetMethod("test3");

            
MethodHolder holderForTest2 = new MethodHolder(thistest2);
            
MethodHolder holderForTest3 = new MethodHolder(thistest3holderForTest22);

            
MethodHolder holderForTest1 = new MethodHolder(thistest2);

            for (var 
05i++)
            {
                
test1(holderForTest12);
                
Console.WriteLine();
                
test1(holderForTest32);
            }
        }
    }

    public class 
MethodHolder
    
{
        private 
MethodInfo _method;
        private 
object _owner;
        private 
object[] _parameters;

        public 
MethodHolder(object ownerMethodInfo methodparams object[] parameters)
        {
            
_owner owner;
            
_method method;
            
_parameters parameters;
        }

        public 
object Invoke()
        {
            var 
result _method.Invoke(_owner_parameters);
            while (
result != null && result.GetType() == typeof(MethodHolder))
            {
                
result = ((MethodHolderresult).Invoke();
            }
            return 
result;
        }
    } 
Тут мы делаем неких MethodHolder, который в себе хранит ссылку на метод. Он может быть вложеным.В данном случае мы вложили вызов один в другой. И в данном случае для одного проходы вывод такой:
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. Так как, мой вариант, отдаёт сильно корявостью.
09.11.2009 16:54
*Ihor* Пытался хитрить с 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);
            }
        }
    }
}
получаю ругательство что test3 variable used as method
05.11.2009 18:41
PhoeniXX Так же существует ANTLR http://www.antlr.org/. Он нужен для создания парсера на основе некой грамматики. В принципе он довольно неплох, и позволяет уйти от изобретения велосипеда.
Ему нужно сделать грамматику операций, и он потом на её основе сделает парсер по этой грамматике. Парсер он может делать на разных языках. Помню там был C#, Java, и C++ вроде.

PhoeniXX добавил 05.11.2009 в 19:45
В самом ANTLR-е есть много примеров грамматик. Так же есть пример простого мат калькулятора.

PhoeniXX добавил 05.11.2009 в 19:53
Вот к примеру sample-овая грамматика для простейшего калькулятора. Действия +, *, (,). По такому принципу вполне доделывается остальные нужные дейсвтия. Данный пример для Java, но отличий, в данном случае, почти никаких нет.
Грамматика:
PHP код:
class CalcParser extends Parser;
options {
    
buildAST true;    // uses CommonAST by default
}

expr
    
:    mexpr (PLUSmexpr)* SEMI!
    ;

mexpr
    
:    atom (STARatom)*
    ;

atom:    INT
    
;

class 
CalcLexer extends Lexer;

WS    :    (' '
    
|    '\t'
    
|    '\n'
    
|    '\r')
        { 
_ttype Token.SKIP; }
    ;

LPAREN:    '('
    
;

RPAREN:    ')'
    
;

STAR:    '*'
    
;

PLUS:    '+'
    
;

SEMI:    ';'
    
;

protected
DIGIT
    
:    '0'..'9'
    
;

INT    :    (DIGIT)+
    ;

class 
CalcTreeWalker extends TreeParser;

expr returns [float r]
{
    
float a,b;
    
r=0;
}
    :    
#(PLUS a=expr b=expr)    {r = a+b;}
    
|    #(STAR a=expr b=expr)    {r = a*b;}
    
|    i:INT            {= (float)Integer.parseInt(i.getText());}
    ; 
05.11.2009 07:02
Honer
Цитата:
Сообщение от *Ihor* Посмотреть сообщение
последний вариант более корректный, но вот незадача с обращением внутри Test1() как val.Value - что сразу убивает вариант Test1(val+3,2)
тут больше LINQ подходит для решения задачи аналогичной SQL где таже AVG() может принимать и колонку и выражение и т.д. Но вот немогу осилить это таким образом чтобы вызов был в примитивах
test1(test2+test3/3,2)*test1(test3+test2/3, 2) для примера.
Т.е. попытка пойти логикой Плагина. Вводится код понятный юзверу, который вставляется в темплейт и генерится как плагин и отрабатывает. SQL вроде как является интерпритатором, но сама мысль парсить на разделители и обрабатывать просто ужасает.
Здесь нужен математический парсер. Там логика простая. Я когда то реализовывал под такую задачу мат парсер. Во первых в таком синтаксисе есть иерархия операций.
05.11.2009 02:01
*Ihor*
Цитата:
Сообщение от PhoeniXX Посмотреть сообщение

public void StartTest()
{
ValueMemento val = new ValueMemento
();
for (var
i = 0; i < 5; i
++)
{
Test1(val, 2
);
}
}
последний вариант более корректный, но вот незадача с обращением внутри Test1() как val.Value - что сразу убивает вариант Test1(val+3,2)
тут больше LINQ подходит для решения задачи аналогичной SQL где таже AVG() может принимать и колонку и выражение и т.д. Но вот немогу осилить это таким образом чтобы вызов был в примитивах
test1(test2+test3/3,2)*test1(test3+test2/3, 2) для примера.
Т.е. попытка пойти логикой Плагина. Вводится код понятный юзверу, который вставляется в темплейт и генерится как плагин и отрабатывает. SQL вроде как является интерпритатором, но сама мысль парсить на разделители и обрабатывать просто ужасает.
30.10.2009 17:45
Honer
Цитата:
Сообщение от *Ihor* Посмотреть сообщение
Есть головоломка которую пытаюсь долго и нужно решить на C#
По логике все было понятно а вот в реальности работа компилятора , да и сами законы C# сделали обратное.

Задача в том что нужен синтаксис вызова методов определенной структуры:
PHP код:
[size=2][font=Consolas]    test1(test22);
[
size=2][font=Consolas]    test1(test2*2+test2/32);[/font][/size]
[
size=2][font=Consolas][/font][/size][/font][/size

через проперти все вроде реально, и все работает , за искючением ситуации, что test1 получает test2 и даже test2() в статичном виде, я так понимаю на этапе компиляции. А вот нужно чтобы вызов был динамичный. Т.е. test1() получал , какбы не значение а сылку на метод и при обращении ее запускал по типу eval().
Головоломка пока оказалась не позубам, перепробовла тучи вариантов.

Вот ниже пример кода для теста в котором обращение к test2 идет 2 раза на цикл, но реально консоль показывает что в каждом цикле test1 значение test2 одинаковое


PHP код:
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
    public 
partial class Form1 Form
    
{
      public 
Form1()
      {
            
InitializeComponent();
      }
      public 
int count 0;
      public 
int test1(int valint exp)
      {
         for (
int i 0expi++) 
         {
           
Console.Write(val);
          }
         return 
1;
      }
      public 
int test2
      
{
           
get
           
{
              
count += 1;
              return 
count;
           }
      }
      private 
void button1_Click(object senderEventArgs e)
      {
         for (var 
05i++)
            { 
                 
test1(test22);
             }
        }
     }

Консоль в этом варианте имеет вид: 1122334455 вместо 12345678910
Привет. Есть такая проблема в этом проекте. Если не решил, то обращайся. Помогу
29.10.2009 11:33
PhoeniXX Привет, Здесь проблема более концептуальная.
Дело в том что все типы в .Net-е деляется на Value и Reference типы. Int (как и многие простые типы) относится к Value типами. А Value тип при передаче параметром копирует своё значение. И в данном случае он один раз вычисляется при каждом вызове Test2, и результат уже идет дальше в вызов без привязки к свойству.

Можно сделать так через анонимный метод:
PHP код:
public class Test
    
{
        public 
int count 0;

        public 
delegate int GetValueHandler();

        public 
int test1(GetValueHandler valHandlerint exp)
        {            
            for (
int i 0expi++)
            {
                
int val valHandler();
                
Console.Write(val);
            }
            return 
1;
        }

        public 
int Test2
        
{
            
get
            
{
                return ++
count;
            }
        }

        public 
void StartTest()
        {
            for (var 
05i++)
            {
                
test1(
                    
delegate() { return Test2; }, 
                    
2);
            }
        }
    } 
PhoeniXX добавил 29.10.2009 в 12:35
Хотя в данном случае Reference тип вел бы себя так же наверно. Проблема была в том что передавалась не ссылка на геттер свойсвта Test2, а само полученное значение этого свойсвта.

PhoeniXX добавил 29.10.2009 в 12:40
Можно еще сделать так:
PHP код:
   public class Test
    
{
        private 
int count 0;

        public 
int Test1(MethodInfo valHandlerint exp)
        {            
            for (
int i 0expi++)
            {
                
int val = (int)valHandler.Invoke(thisnull);
                
Console.Write(val);
            }
            return 
1;
        }

        public 
int Test2
        
{
            
get { return ++count; }
        }

        public 
void StartTest()
        {
            for (var 
05i++)
            {
                
Test1(GetType().GetProperty("Test2").GetGetMethod(), 2);
            }
        }
    } 
Здесь идет прямое обращение к геттеру свойства через Reflection. Но этот пример более некрасив, и более ресурсоёмкий. Это просто как пример, как можно сделать по другому.
Или можно просто напрямую в методе Test1 обращятся к свойсвту Test2

PhoeniXX добавил 29.10.2009 в 19:08
А вот еще более корректный ООП вариант:
PHP код:
        public class ValueMemento
        
{
            private 
int _count 0;

            public 
int Value
            
{
                
get { return ++_count; }
            }
        }

        public class 
Test
        
{
            public 
void Test1(ValueMemento valint exp)
            {
                for (
int i 0expi++)
                {
                    
Console.Write(val.Value);
                }
            }

            public 
void StartTest()
            {
                
ValueMemento val = new ValueMemento();
                for (var 
05i++)
                {
                    
Test1(val2);
                }
            }
        } 
То есть передавать класс хранящий внутри себя нужные значение.
29.10.2009 00:22
*Ihor*
Головоломка для C#

Есть головоломка которую пытаюсь долго и нужно решить на C#
По логике все было понятно а вот в реальности работа компилятора , да и сами законы C# сделали обратное.

Задача в том что нужен синтаксис вызова методов определенной структуры:
PHP код:
[size=2][font=Consolas]    test1(test22);
[
size=2][font=Consolas]    test1(test2*2+test2/32);[/font][/size]
[
size=2][font=Consolas][/font][/size][/font][/size

через проперти все вроде реально, и все работает , за искючением ситуации, что test1 получает test2 и даже test2() в статичном виде, я так понимаю на этапе компиляции. А вот нужно чтобы вызов был динамичный. Т.е. test1() получал , какбы не значение а сылку на метод и при обращении ее запускал по типу eval().
Головоломка пока оказалась не позубам, перепробовла тучи вариантов.

Вот ниже пример кода для теста в котором обращение к test2 идет 2 раза на цикл, но реально консоль показывает что в каждом цикле test1 значение test2 одинаковое


PHP код:
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
    public 
partial class Form1 Form
    
{
      public 
Form1()
      {
            
InitializeComponent();
      }
      public 
int count 0;
      public 
int test1(int valint exp)
      {
         for (
int i 0expi++) 
         {
           
Console.Write(val);
          }
         return 
1;
      }
      public 
int test2
      
{
           
get
           
{
              
count += 1;
              return 
count;
           }
      }
      private 
void button1_Click(object senderEventArgs e)
      {
         for (var 
05i++)
            { 
                 
test1(test22);
             }
        }
     }

Консоль в этом варианте имеет вид: 1122334455 вместо 12345678910

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Выкл.
Pingbacks are Выкл.
Refbacks are Выкл.

Время на сервере: 09:20.

Регистрация Справка Пользователи Календарь Сообщения за день

vBulletin 3, Copyright © 2000-2024, Jelsoft Enterprises Ltd.
Русский перевод: zCarot, Vovan & Co