Показать сообщение отдельно
Старый 11.11.2023, 18:37   #1  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,160 / 1289 (47) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
DAX2012 тип dot net System.Object и тип X++ real с CIL как правильно работать?
Добрый день.
Есть работа с внешней базой, используется System.Data.SqlClient.SqlDataReader.

Его свойство Item[...] (в Аксе используем метод get_Item(...)) возвращает System.Object.
Для полей вещественных типов возвращается System.Double.

Для получения значений Аксы вполне работал способ:
X++:
System.Object   sysObj;
anytype ret;

sysObj = dataReader.get_Item(_fieldNum);
ret = ClrInterop::getAnyTypeForObject(_sysObj);
Как только понадобилось запустить это в пакете (то есть с CIL) именно для System.Double getAnyTypeForObject не работает - возвращает не значение базового типа real, а объект System.Double.

Естественно, понять что именно не работает удалось только в отладчике VS.

Понятно, что конкретный случай получилось обойти путем написания кучи кода:
X++:
protected anytype systemObjectToAnyType(System.Object _sysObj)
{
    anytype         ret;
    System.Type     retType;
    str             retTypeName;
    str             valueStr;
    boolean         useStdConvert;
    ;

    useStdConvert   = true;
    if (xSession::isCLRSession())
    {
        retType = _sysObj.GetType();
        retTypeName = retType.get_Name();
        if (retTypeName == 'double')
        {
            // Весёлости взаимодействия System.Double и real X++.
            // Стандарт не конвертирует, приходится выполнять закат солнца вручную.
            valueStr    = _sysObj.ToString();
            ret = str2num_RU(valueStr);
            useStdConvert   = false;
        }
    }

    if (useStdConvert)
    {
        // BP deviation documented
        ret = ClrInterop::getAnyTypeForObject(_sysObj);
    }

    return ret;
}
Может я тут что-то перемудрил и есть более простые варианты?
В стандартном приложении нашел много кода, когда наоборот - имеем переменную real X++ и нужно передать туда, где требуется System.Double - даже в global метод для этого создали. Видимо сталкивались с проблемами преобразования в CIL real->System.Double. А вот ситуации когда имеем System.Double и нужно просто присвоить её real X++ не обнаружил.