|
22.10.2009, 10:36 | #1 |
Участник
|
Как работает тернарный оператор
Почему для этого кода, в предпоследней строке, вываливает ошибка "Типы операнда не совместимы с оператором.":
X++: return _cmd == Command::CopyAll ? new EditCopyAll () : _cmd == Command::Copy ? new EditCopy () : _cmd == Command::MoveAll ? new EditMoveAll () : _cmd == Command::Move ? new EditMove () // ошибка "Типы операнда не совместимы с оператором." : null; X++: return _cmd == Command::CopyAll ? new EditCopyAll () //: _cmd == Command::Copy ? new EditCopy () //: _cmd == Command::MoveAll ? new EditMoveAll () //: _cmd == Command::Move ? new EditMove () : null; Это очередная баго-фича или есть смысл в таком поведении?
__________________
Dynamics AX 4.0.2501.122 SP2, kernel 4.0.2163.0, MS SQL 2005 |
|
22.10.2009, 10:45 | #2 |
Ищущий знания...
|
странный код... это метод construct() какого то класса? это код стандартного функционала?
может просто привык, но обычно в construct() используется оператор switch... теперь по существу, предположу что класс EditMove не является наследником класса, который инициализируется.
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
22.10.2009, 11:02 | #3 |
Участник
|
С наследованием все в порядке.
Код свой. Для меня такой код выглядит более "чистым" и декларативным чем switch. Обратите внимание, что условия могут буть сколько угодно сложными. Второе, компилятор требует обязательно вернуть значение, а это более и безопасно и более читаемо, явно видно какой результат хочет получить программист который это писал. А а не просто "делай то не знаю что". Ну где-то так.
__________________
Dynamics AX 4.0.2501.122 SP2, kernel 4.0.2163.0, MS SQL 2005 |
|
|
За это сообщение автора поблагодарили: miklenew (-1). |
22.10.2009, 11:15 | #4 |
Ищущий знания...
|
X++: static MyClass construct(TypeRun _typeRun) { MyClass retClass; switch(_typeRun) { case 1 : retClass = new MyClass_1(); break; case 2 : retClass = new MyClass_2(); break; default : retClass = new MyClass(); } return retClass; }
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
22.10.2009, 11:18 | #5 |
Участник
|
Попробуйте взять в скобки вложенные операторы.
X++: return _cmd == Command::CopyAll ? new EditCopyAll () : (_cmd == Command::Copy ? new EditCopy () : (_cmd == Command::MoveAll ? new EditMoveAll () : (_cmd == Command::Move ? new EditMove (): null))); // ошибка "Типы операнда не совместимы с оператором."
__________________
Axapta v.3.0 sp5 kr2 |
|
22.10.2009, 12:17 | #6 |
Участник
|
Цитата:
Сообщение от AndyD
Попробуйте взять в скобки вложенные операторы.
X++: return _cmd == Command::CopyAll ? new EditCopyAll () : (_cmd == Command::Copy ? new EditCopy () : (_cmd == Command::MoveAll ? new EditMoveAll () : (_cmd == Command::Move ? new EditMove (): null))); // ошибка "Типы операнда не совместимы с оператором."
__________________
Dynamics AX 4.0.2501.122 SP2, kernel 4.0.2163.0, MS SQL 2005 Последний раз редактировалось cerbo; 22.10.2009 в 12:19. |
|
22.10.2009, 12:41 | #7 |
Участник
|
Вот так заработало:
X++: return _cmd == Command::CopyAll ? EditCopyAll::construct () : _cmd == Command::Copy ? EditCopy::construct () : _cmd == Command::MoveAll ? EditMoveAll::construct () : _cmd == Command::Move ? EditMove::construct () : null; Похоже действительно лажает компилятор, конструктор здесь имеет какое-то особое значение. Все это ребята не весело
__________________
Dynamics AX 4.0.2501.122 SP2, kernel 4.0.2163.0, MS SQL 2005 |
|
22.10.2009, 12:48 | #8 |
Участник
|
|
|
22.10.2009, 13:17 | #9 |
Сенбернар
|
__________________
Best Regards, Roman |
|
22.10.2009, 13:42 | #10 |
Участник
|
Господа хорошие. Пост вообще-то был о проблемах компилятора, а не про стиль программирование. Я не хочу с вами спорить, но вы не правы.
__________________
Dynamics AX 4.0.2501.122 SP2, kernel 4.0.2163.0, MS SQL 2005 |
|
22.10.2009, 11:19 | #11 |
Ищущий знания...
|
по проблеме.
Думаю должна помочь инкрементная компиляция класса родителя
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
22.10.2009, 15:47 | #12 |
Участник
|
Альтернативное извращение
X++: #localMacro. case Command::%1: return new Edit%1(); #endmacro switch (_cmd) { #(CopyAll) #(Copy) #(MoveAll) #(Move) } return null X++: new SysDictClass(className2ID('Edit' + new DictEnum(enumNum(Command)).valueToSymbol(_cmd))).makeObject() НЕ ИСПОЛЬЗОВАТЬ В РАБОЧЕМ КОДЕ Последний раз редактировалось belugin; 22.10.2009 в 15:54. |
|
|
За это сообщение автора поблагодарили: miklenew (1). |
22.10.2009, 17:22 | #13 |
Ищущий знания...
|
понимаете, правила придумываются не просто так. Правила - это стандартизация определенных действий, понятных всем людям.
Если говорите про нашу программу, то правила были придуманы, что бы любой программист мог поддерживать код в программе. Если каждый будет писать по своему принципу, то будет полный огород, и поддержка будет мукой. Мне тоже некоторые принципы не понятны в аксапте, а вначале их было ещё больше, однако все равно стараюсь следовать правилам.
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
|
За это сообщение автора поблагодарили: blokva (1). |
22.10.2009, 17:24 | #14 |
----------------
|
Вам даже компилятор "сказал", что это неBestPractices, попробуйте его убедить в обратном
|
|
22.10.2009, 18:09 | #15 |
Участник
|
|
|
22.10.2009, 17:32 | #16 |
MCT
|
Знавал одного "архитектора", который как раз очень любил такие вещи и всегда надменно про себя говорил - этот не индусский код. По делам этот работничек сделал модуль, который состоял из четырех таблиц, которые содержали одинаковые по составу поля и при вставке данные прописывались по всем четырем таблицам. Красоты архтектуры не было, то есть вообще архитекруры не было. ИМХО надо делать все в меру.
Думаю что более "гикнуто" было вообще писать код в одну строчку X++: #localMacro. case Command::%1: return new Edit%1(); #endmacro switch (_cmd){ #(CopyAll) #(Copy) #(MoveAll) #(Move) } return null
__________________
Axapta book for developer |
|
22.10.2009, 17:51 | #17 |
Сенбернар
|
- Вырезано Модератором: На личности не переходим -
Не. Никогда Просто - мозг снесло у парня. КМК Последний раз редактировалось RVS; 22.10.2009 в 18:22. |
|
22.10.2009, 18:16 | #18 |
Участник
|
Я так вижу, что либо вы не читали либо не поняли моих объяснений.
Попробую более подробно разъяснить. Смысл, то в том, что когда от выражения требуется вернуть значение, то:
То есть: X++: switch(value) { case cond1 : action1 case cond2 : action2 default : default_action } X++: result= cond1 ? result1 : cond2 ? result2 : default_result; То же и с функциями. Если функция void, то есть основания для беспокойства- внутри нее 100% изменяется состояние объектов, а иначе она не была бы void. Если не void то немного проще потому, что наперед известно чем все закончится.
__________________
Dynamics AX 4.0.2501.122 SP2, kernel 4.0.2163.0, MS SQL 2005 |
|
22.10.2009, 18:30 | #19 |
Administrator
|
Есть замечательное правило, очень хорошо применимое к системе, в которой УЖЕ есть код. Называется оно "Пусть безобразно, зато однообразно".
Т.е. никто не оценит усилия по улучшению читабельности отдельно взятого кода, если в остальных 255 местах он написан по-другому. Микрософт делает шаги в этом направлении - и только они имеют право это делать как ее владельцы. Если представить себе, что весь код будет переписан с нуля - то да, конечно можно пересмотреть все и вся. А в АХ надо учитывать, что это не язык программирования в полном понимании и его компилятор не отлаживался полноценно (Вы уже успели с этим столкнуться). Поэтому написание кода "по аналогии" связано еще с заведомым обходом "косяков" компилятора. Так что "массовость" существующего кода - сильно давит на всех остальных разработчиков - в т.ч. из МС (даже они оказались не готовы отказаться от X++ в пользу того же C#)
__________________
Возможно сделать все. Вопрос времени |
|
22.10.2009, 18:34 | #20 |
Участник
|
Цитата:
1. Так не делают, поэтому инструментарием данный путь не поддерживается 2. Так не делают, поэтому средний человек, читающий ваш код вместо знакомого паттерна будет долго тупить 3. нету case condition, есть case value - а вам приходится каждый раз повторять _cmd == 4. Лучше безобразно, но единообразно (via подполковник Схаба) => На практике, лучше switch Последний раз редактировалось belugin; 22.10.2009 в 18:36. |
|