Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.156] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 169 170 [171] 172 173 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#2551
,
|
|
|
|
|
Сообщ.
#2552
,
|
|
|
|
Цитата IL_Agent @ Никакой магии, всё очень просто. В отличие от. ![]() я имею в виду привязку имен методов к именам элементов перечислений. это не есть хорошо. |
|
Сообщ.
#2553
,
|
|
|
|
Цитата IL_Agent @ Никакой магии, всё очень просто. В отличие от. Просто было бы атрибутом пометить методы, а вот на их имена закладываться, это, простите мою прямоту, моветон. |
|
Сообщ.
#2554
,
|
|
|
|
Цитата korvin @ я имею в виду привязку имен методов к именам элементов перечислений. это не есть хорошо. Цитата MyNameIsIgor @ Просто было бы атрибутом пометить методы, а вот на их имена закладываться, это, простите мою прямоту, моветон. Привязываться можно к чему угодно. Суть в том, что не надо модифицировать Dispatch, создавать хранилища для методов и т.д. и т.п. |
|
Сообщ.
#2555
,
|
|
|
|
Цитата IL_Agent @ Привязываться можно к чему угодно. Суть в том, что не надо модифицировать Dispatch, создавать хранилища для методов и т.д. и т.п. ни мне, ни Игорю не нужно модифицировать dispatch, зато тебе при модификации элементов перечислений придется переименовывать методы =) |
|
Сообщ.
#2556
,
|
|
|
|
Цитата korvin @ А что тебе придется сделать при изменении Bar на:зато тебе при модификации элементов перечислений придется переименовывать методы =) ![]() ![]() enum Bar {A, B, D, E, C}; |
|
Сообщ.
#2557
,
|
|
|
|
Цитата volvo877 @ А что тебе придется сделать при изменении Bar на: ![]() ![]() enum Bar {A, B, D, E, C}; переставить местами описания методов? это еще зачем? а менять размер массива -- это одно действие, в отличие от переименовывание потенциально (M x N) методов |
|
Сообщ.
#2558
,
|
|
|
|
![]() ![]() template<typename T> class enum_metrix{}; enum Foo {X, Y}; enum Bar {A, B, C, D}; template<> class enum_metrix<Foo> { public: enum{size = 2}; enum{min = X}; enum{max = Y}; }; template<> class enum_metrix<Bar> { public: enum{size = 4}; enum{min = A}; enum{max = D}; }; class Gee { private: typedef void (Gee::*handler)(); private: static handler _handlers[enum_metrix<Foo>::size][enum_metrix<Bar>::size]; private: template<Foo foo, Bar bar> void m(){}; template<Foo foo, Bar bar> class _init_bar { public: inline _init_bar() { _handlers[foo][bar] = &m<foo, bar>; _init_bar<foo, static_cast<Bar>(bar - 1)>(); } }; template<Foo foo> class _init_bar<foo, static_cast<Bar>(enum_metrix<Bar>::min)> { public: inline _init_bar() { _handlers[foo][enum_metrix<Bar>::min] = &m<foo, static_cast<Bar>(enum_metrix<Bar>::min)>; } }; template<Foo foo> inline static void _init_foo() { _init_bar<foo, static_cast<Bar>(enum_metrix<Bar>::max)>(); _init_foo<static_cast<Foo>(foo - 1)>(); } template<> inline static void _init_foo<static_cast<Foo>(enum_metrix<Foo>::min)>() { _init_bar<static_cast<Foo>(enum_metrix<Foo>::min), static_cast<Bar>(enum_metrix<Bar>::max)>(); } public: static void init() { _init_foo<static_cast<Foo>(enum_metrix<Foo>::max)>(); } void dispatch(Foo foo, Bar bar) { (this->*_handlers[foo][bar])(); } }; Gee::handler Gee::_handlers[enum_metrix<Foo>::size][enum_metrix<Bar>::size]; template<> void Gee::m<X, A>() { std::cout << "X A" << std::endl; } template<> void Gee::m<X, B>() { std::cout << "X B" << std::endl; } template<> void Gee::m<X, C>() { std::cout << "X C" << std::endl; } template<> void Gee::m<X, D>() { std::cout << "X D" << std::endl; } template<> void Gee::m<Y, A>() { std::cout << "Y A" << std::endl; } template<> void Gee::m<Y, B>() { std::cout << "Y B" << std::endl; } template<> void Gee::m<Y, C>() { std::cout << "Y C" << std::endl; } template<> void Gee::m<Y, D>() { std::cout << "Y D" << std::endl; } int _tmain(int argc, _TCHAR* argv[]) { Gee::init(); Gee gee; gee.dispatch(Y, C); gee.dispatch(X, A); return 0; } |
|
Сообщ.
#2559
,
|
|
|
|
Цитата IL_Agent @ Привязываться можно к чему угодно. Не, привязываться надо к женщине ![]() Цитата IL_Agent @ Суть в том, что не надо модифицировать Dispatch Так его и не модифицируют... Цитата IL_Agent @ создавать хранилища для методов и т.д. и т.п. А чем это плохо то? Я имел в виду сделать на шарпе что-то типа этого ![]() ![]() using System; using System.Collections.Generic; using System.Reflection; using System.Linq; enum Foo { A, B, C } enum Bar { X, Y } class Gee { public Foo f; public Bar b; class ProcAttribute : Attribute { public Foo Foo; public Bar Bar; } [Proc(Foo = Foo.A, Bar = Bar.X)] void mAX() { Console.WriteLine("mAX"); } [Proc(Foo = Foo.B, Bar = Bar.X)] void mBX() { Console.WriteLine("mBX"); } static Dictionary<KeyValuePair<Foo, Bar>, Action<Gee>> methods = new Dictionary<KeyValuePair<Foo, Bar>, Action<Gee>>(); static Gee() { var procs = from p in (from m in typeof(Gee).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance) select new { method = m, attribute = m.GetCustomAttributes(typeof(ProcAttribute), false).FirstOrDefault() as ProcAttribute }) where p.attribute != null select p; foreach(var proc in procs) { var method = proc.method; methods.Add(new KeyValuePair<Foo, Bar>(proc.attribute.Foo, proc.attribute.Bar), g => method.Invoke(g, null)); } } public void dispatch() { methods[new KeyValuePair<Foo, Bar>(f, b)](this); } } class Program { public static void Main() { var gee = new Gee() { f = Foo.A, b = Bar.X }; gee.dispatch(); gee.f = Foo.B; gee.dispatch(); } } Добавлено Повстанець, ага, шаблоны рулят, только korvin'у вряд ли понравится Только ещё вызов Gee::init сделать неявным |
|
Сообщ.
#2560
,
|
|
|
|
Цитата MyNameIsIgor @ Повстанець, ага, шаблоны рулят На самом деле рулят алгебраические типы данных и мультиметоды, но это уже оффтоп... |
|
Сообщ.
#2561
,
|
|
|
|
Цитата MyNameIsIgor @ А чем это плохо то? А чего хорошего-то ? ![]() Цитата MyNameIsIgor @ Я имел в виду сделать на шарпе что-то типа этого И зачем ? Проблему Цитата korvin @ это не решает, т.к. [Proc(Foo = Foo.A, Bar = Bar.X)] таки привязывается к именам элементов перечисления, а отнюдь не к женщине модификации элементов перечислений ![]() Цитата korvin @ а менять размер массива -- это одно действие, в отличие от переименовывание потенциально (M x N) методов Переименовать методы можно с помощью find/replace - тоже одно действие. Ещё можно методы называть как-нибудь вроде m_0_1, тогда переименовывать их не придётся. А вот если enum Foo {X = -1, Y = 100}, то массивы не катят. Но это все флейм. Поставленная задача данным способом полностью решается, и очень просто, в отличие от. И да, если эта задача возникла из-за отсутствия мультиметодов, то в шарпе они очень даже прикручиваемы. |
|
Сообщ.
#2562
,
|
|
|
|
Цитата IL_Agent @ Переименовать методы можно с помощью find/replace - тоже одно действие. ээ... было так: ![]() ![]() enum Foo { X, Y }; enum Bar { A, B }; ... void XA (); void XB (); void YA (); void YB (); ... стало так: ![]() ![]() enum Foo { U, V }; enum Bar { M, N }; ... void XA (); void XB (); void YA (); void YB (); ... как переименовать эти четыре метода в одно действие с помощью find/replace? Добавлено Цитата IL_Agent @ И да, если эта задача возникла из-за отсутствия мультиметодов, то в шарпе они очень даже прикручиваемы. не обязательно мультиметодов, сопоставление с образцом тоже здорово помогает Скрытый текст первое же прикручивание по ссылке является неполным и не обладает нужной тут фишкой -- диспетчеризацией по конкретным объектам. т.е. в мультиметодах CL это решается так: ![]() ![]() (defmethod dispatch ((x gee) (foo (eql :x)) (bar (eql :a))) (format t "XA~%")) |
|
Сообщ.
#2563
,
|
|
|
|
Цитата IL_Agent @ [Proc(Foo = Foo.A, Bar = Bar.X)] таки привязывается к именам элементов перечисления Однако же, во-первых, эту привязку отслеживает IDE и потому рефакторится легко и непринуждённо, а не дебильным дедовским find/replace. А во-вторых, достигнуто главное - убрана эта ваша неявная привязка имён методов к именам элементов перечислений, которую IDE не поймёт и отрефакторить не поможет. |
|
Сообщ.
#2564
,
|
|
|
|
Цитата korvin @ как переименовать эти четыре метода в одно действие с помощью find/replace? Ну если закладываться на последующие переименование (а не подумать нормально над именами сразу), то можно именовать а ля method_Foo_A_Bar_X, например. Цитата MyNameIsIgor @ Однако же, во-первых, эту привязку отслеживает IDE и потому рефакторится легко и непринуждённо Чего отслеживать-то ? Ну вот понадобилось переименовать. Я делаю find/replace и вуаля. А вы как будете ? Цитата MyNameIsIgor @ дебильным дедовским find/replace Ой, ну это уже похоже на батхерт. ![]() Цитата MyNameIsIgor @ А во-вторых, достигнуто главное - убрана эта ваша неявная привязка имён методов к именам элементов перечислений Ну если у вас это главное - то ладно |
|
Сообщ.
#2565
,
|
|
|
|
Цитата IL_Agent @ Чего отслеживать-то ? Ну вот понадобилось переименовать. Я делаю find/replace и вуаля. Да что-то не очень "вуаля". Вы же сами, отвечая на вопрос korvin'а, сказали, что ещё и методы надобно подобающим образом обозвать. Цитата IL_Agent @ А вы как будете ? А я в VS/MonoDevelop встану курсорчиком на нужный элемент enum'а, нажму F2, вобью новое имя и нажму Enter. Но если вы так страстно любите допотопную текстовую замену, то можете так же репласить - при пометке атрибутом явно пишется: Foo.A. Вот и заменяйте на новое имя - не вижу проблем. Цитата IL_Agent @ Ну если у вас это главное - то ладно Это как минимум важно. В вашем коде связь имён элементов перечислений и методов неявная, что не может считаться хорошим решением. |