Добрый день.
Есть работа с внешней базой, используется 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++ не обнаружил.