29.12.2020, 09:47 | #21 |
Участник
|
Цитата:
class MyClass { MyClass test(){ return null } } class MyExtendedClass extends MyClass { SysAnyType test(){ return null } } Цитата:
1. что можно сделать с подобными тренарными операторами в ax2012? (примеры рассыпаны выше по ветке)
Цитата:
2. почему и зачем это возникло в ax2012 на твой взгляд? понятно, что для совместимости в CIL.
Цитата:
А в CIL это зачем и почему раньше этого в X++ не было?
В X++ до 2012 нет гарантии, что если ты вызвал метод x на переменной типа y ты вызовется именно метод класса y. В переменной может лежать объект любого класса и, если у него есть метод x то вызовется он. А если нет, то будет исключение. Причем не когда возникает несовместимое присваивание, а когда вызов, что может быть гораздо позже и труднее искать основную причину ошибки. Цитата:
3. какова ситуация с тренарными операторами в D365FO и почему так случилось?
Warning 'as' is obsolete: '"Use the AS operator instead."' Цитата:
4. а также любые твои мысли на тему ветки - будет интересно.
Потом решили приделать CIL и привести в соответствие типизацию компилятора и рантайма. Чтобы раньше получать сообщения об ошибках. С тернарным оператором что-то не так - я думаю какая-то ошибка или недоделка в выводе типов. В Dyn365FO компилятор переписали на C# (Вернее, доделали XLNT, который занимался раньше просто дополнительными проверками) и эту недоделку устранили, насколько я вижу. |
|
|
За это сообщение автора поблагодарили: Logger (3). |
29.12.2020, 09:48 | #22 |
Участник
|
Цитата:
Сообщение от mazzy
Чтобы было полезно и познавательно читателям аксфорума
можешь (без оглядки на мои ответы) сформулировать в одном посте: 1. что можно сделать с подобными тернарными операторами в ax2012? (примеры рассыпаны выше по ветке) 2. почему и зачем это возникло в ax2012 на твой взгляд? понятно, что для совместимости в CIL. А в CIL это зачем и почему раньше этого в X++ не было? 3. какова ситуация с тернарными операторами в D365FO и почему так случилось? 4. а также любые твои мысли на тему ветки - будет интересно. Как-то мало кто прореагировал. Вопросы интересные и нужные на практике. |
|
02.01.2021, 18:08 | #23 |
Участник
|
Цитата:
Т.е. типы в методах потомках не проверяются на хоть какое-нибудь соответствие типам родителей. Типы проверяются только при присваивании (явном или неявном). Убедил. |
|
|
За это сообщение автора поблагодарили: belugin (5). |
20.01.2021, 17:38 | #24 |
Участник
|
Цитата:
Сообщение от mazzy
гуглить в сторону "ковариантность" и "инвариантность".
https://ru.wikipedia.org/wiki/%D0%9A...D%D0%B8%D0%B5) в java изначально типы ковариантны. и дополнительно было очень много послаблений в примитивных типах. в аксапте изначально добавили ковариантность в методы классов. что позволяло до ax2009 указывать производные типы методах классов наследников (уж не знаю по недосмотру или был какой замысел). в ax2012 с какого-то перепуга разработчики сделали типы инвариантными как в C# 2.0. причем очень жестко. из-за этого нельзя уточнять тип в параметрах методов и в возвращаемых значениях. в качестве побочного эффекта получили вот такие затыки в тренарных операторах, а также в map (который AOT). Оставлю тут https://docs.microsoft.com/en-us/arc...the-x-language X++: Forthcoming changes to the X++ language https://docs.microsoft.com/en-us/arc...namics-ax-2012 |
|
30.08.2023, 16:27 | #25 |
Участник
|
Цитата:
Сообщение от Logger
4-й вопрос. - Кто как обходит такое поведение компилятора?
пока вижу такие способы а. Отказаться от тернарного оператора в случае когда выдает ругань. б. Использовать any2XXX функции, дописав недостающие самим в global классе. Есть ли в этом какой то риск в случае CIL ? в. Забить на предупреждения компилятора (а как их тогда подавить корректно ? Грубые хаки в виде кода на insert / write методах таблицы TmpCompilerOutput c запретом вставки записи - я не считаю. Это крайний вариант) г. ... сделать в Global метод X++: public static anytype tern(boolean _useFirst, anytype _parmFirstValue, anytype _parmSecondValue) { ; if (_useFirst) { return _parmFirstValue; } return _parmSecondValue; } Такой ли уж это г. способ ? |
|
30.08.2023, 17:33 | #26 |
Участник
|
Забить на Микрософт.
Также как Микрософт забил на нас. |
|
30.08.2023, 17:34 | #27 |
Участник
|
|
|
30.08.2023, 17:47 | #28 |
Участник
|
У варианта "г" будет особенность, что оба выражения будут вычисляться (выполняться) в любом случае, в отличие от тернарного оператора.
Помимо оптимизации это не всегда допустимо. |
|
|
За это сообщение автора поблагодарили: Logger (3). |
29.09.2023, 17:37 | #29 |
Участник
|
Цитата:
X++: static void tern_macro_test(Args _args) { #localmacro.tern if (%2) { %1 = %3; } else { %1 = %4; } #endmacro anytype value, firstValue, secondValue; boolean useFirst; ; useFirst = true; firstValue = 1; secondValue = 2; #tern(value, useFirst, firstValue, secondValue) info(strfmt("%1", value)); }
__________________
aLL woRk aNd nO JoY MAKes jAck a dULL Boy |
|
29.09.2023, 18:08 | #30 |
Участник
|
не подойдет.
Тернарный оператор это выражение. X++: info(callfunc1() ? callfunc1() : callfunc2()); X++: #localmacro.tern %1 ? any2any(%1) : any2any(%2) #endmacro X++: public static anytype any2any(anytype _value) { return _value; } X++: private void method1() { int a; anytype b = ""; ; info(strFmt("%1", (a ? a : b))); // выдает предупреждение info(strFmt("%1", (a ? any2any(a) : any2any(b)))); // не выдает info(strFmt("%1", (#tern(a, b)))); // не выдает } |
|
|
За это сообщение автора поблагодарили: ivas (3). |
29.09.2023, 18:32 | #31 |
Участник
|
Цитата:
X++: static void tern_macro_test(Args _args) { #localmacro.tern #if.empty(%4) %1 ? %2 : %3 #endif #ifnot.empty(%4) if (%2) { %1 = %3; } else { %1 = %4; } #endif #endmacro anytype value, firstValue, secondValue; boolean useFirst; ; useFirst = true; firstValue = 1; secondValue = 2; info(strfmt("%1", #tern(useFirst, firstValue, secondValue))); useFirst = false; #tern(value, useFirst, firstValue, secondValue) info(strfmt("%1", value)); }
__________________
aLL woRk aNd nO JoY MAKes jAck a dULL Boy |
|
Теги |
ax2012, ax2012r3, тернарный оператор |
|
|