AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 29.12.2020, 09:47   #21  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от mazzy Посмотреть сообщение
Эммм... Макс, если честно, то я совсем запутался. А раскручиывать цепочку цитат и контр-вопросов совсем нет никакого желания.
Но совершенно очевидно, что у тебя есть особое мнение по этому поводу.
Также несомненно, что я могу дико ошибаться.
Мне интересно, если бы кто-то у кого под руками есть Ax4 или Ax3 сделал следующий эксперимент.

class MyClass { MyClass test(){ return null } }
class MyExtendedClass extends MyClass { SysAnyType test(){ return null } }

Цитата:
1. что можно сделать с подобными тренарными операторами в ax2012? (примеры рассыпаны выше по ветке)
Можно попробовать ввести промежуточные переменные с определением конкретного типа.

Цитата:
2. почему и зачем это возникло в ax2012 на твой взгляд? понятно, что для совместимости в CIL.
Я думаю, это ошибка или недоделка вывода типов для тернарной операции.

Цитата:
А в CIL это зачем и почему раньше этого в X++ не было?
Тут надо разбираться как работает CIL внутри я это не так хорошо знаю. В том числе с точки зрения безопасности.

В X++ до 2012 нет гарантии, что если ты вызвал метод x на переменной типа y ты вызовется именно метод класса y. В переменной может лежать объект любого класса и, если у него есть метод x то вызовется он.

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

Цитата:
3. какова ситуация с тренарными операторами в D365FO и почему так случилось?
Пример из заголовка и твой пример компилируются без ошибок (после добавления недостающего метода). Только ворнинги:

Warning 'as' is obsolete: '"Use the AS operator instead."'

Цитата:
4. а также любые твои мысли на тему ветки - будет интересно.
Был компилятор написанный на C++ сто лет назад, притворяющийся языком со сторогой статической типизацией, но при этом позволяющий иногда нарушать безобразия.

Потом решили приделать CIL и привести в соответствие типизацию компилятора и рантайма. Чтобы раньше получать сообщения об ошибках. С тернарным оператором что-то не так - я думаю какая-то ошибка или недоделка в выводе типов.

В Dyn365FO компилятор переписали на C# (Вернее, доделали XLNT, который занимался раньше просто дополнительными проверками) и эту недоделку устранили, насколько я вижу.
За это сообщение автора поблагодарили: Logger (3).
Старый 29.12.2020, 09:48   #22  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,940 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от mazzy Посмотреть сообщение
Чтобы было полезно и познавательно читателям аксфорума
можешь (без оглядки на мои ответы) сформулировать в одном посте:
1. что можно сделать с подобными тернарными операторами в ax2012? (примеры рассыпаны выше по ветке)
2. почему и зачем это возникло в ax2012 на твой взгляд? понятно, что для совместимости в CIL. А в CIL это зачем и почему раньше этого в X++ не было?
3. какова ситуация с тернарными операторами в D365FO и почему так случилось?
4. а также любые твои мысли на тему ветки - будет интересно.
Кстати, да.
Как-то мало кто прореагировал.
Вопросы интересные и нужные на практике.
Старый 02.01.2021, 18:08   #23  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от belugin Посмотреть сообщение
Мне интересно, если бы кто-то у кого под руками есть Ax4 или Ax3 сделал следующий эксперимент.

class MyClass { MyClass test(){ return null } }
class MyExtendedClass extends MyClass { SysAnyType test(){ return null } }
ax4. см. скриншоты.

Т.е. типы в методах потомках не проверяются на хоть какое-нибудь соответствие типам родителей. Типы проверяются только при присваивании (явном или неявном).
Убедил.
Миниатюры
Нажмите на изображение для увеличения
Название: 1.PNG
Просмотров: 69
Размер:	117.2 Кб
ID:	13022   Нажмите на изображение для увеличения
Название: 2.PNG
Просмотров: 68
Размер:	147.3 Кб
ID:	13023  

__________________
полезное на axForum, github, vk, coub.
За это сообщение автора поблагодарили: belugin (5).
Старый 20.01.2021, 17:38   #24  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,940 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от 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 is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,940 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от 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  
ТРЕНЕР is offline
ТРЕНЕР
Участник
Аватар для ТРЕНЕР
 
599 / 50 (3) ++++
Регистрация: 11.06.2003
Адрес: Москва
Забить на Микрософт.
Также как Микрософт забил на нас.
Старый 30.08.2023, 17:34   #27  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,940 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от ТРЕНЕР Посмотреть сообщение
Забить на Микрософт.
Также как Микрософт забил на нас.
Собственно речь о том как лучше это сделать.
Так как способ г. это один из вариантов как забить.
Старый 30.08.2023, 17:47   #28  
dit31 is offline
dit31
Участник
 
12 / 13 (1) ++
Регистрация: 16.01.2015
У варианта "г" будет особенность, что оба выражения будут вычисляться (выполняться) в любом случае, в отличие от тернарного оператора.
Помимо оптимизации это не всегда допустимо.
За это сообщение автора поблагодарили: Logger (3).
Старый 29.09.2023, 17:37   #29  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
Цитата:
Сообщение от dit31 Посмотреть сообщение
У варианта "г" будет особенность, что оба выражения будут вычисляться (выполняться) в любом случае, в отличие от тернарного оператора.
Помимо оптимизации это не всегда допустимо.
Макрос?
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  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,940 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от ivas Посмотреть сообщение
Макрос?
не подойдет.
Тернарный оператор это выражение.

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  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
Цитата:
Сообщение от Logger Посмотреть сообщение
не подойдет.
Тернарный оператор это выражение.

X++:
#localmacro.tern
    %1 ? any2any(%1) : any2any(%2)
#endmacro

    info(strFmt("%1", (#tern(a, b)))); // не выдает
но я сам так не делал.
Это можно объединить в один макрос
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, тернарный оператор

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
AX2012: базовые типы и результаты операторов div и mod отличаются в X++ и в CIL gl00mie DAX: Программирование 0 25.09.2014 11:13
Ax3 - Модуль Учет затрат egorych DAX: Функционал 15 12.12.2013 17:58
emeadaxsupport: Inventory closing differences between AX4.0 and AX2012 using weighted average costing method Blog bot DAX Blogs 0 27.12.2012 19:11
роли, типы пользователей и лицензирование AX2012 wojzeh DAX: Администрирование 1 22.07.2011 23:50
Date Daido DAX: Программирование 6 28.09.2007 11:05
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 23:00.