up-ну тему.
Стали причесывать код. Там где раньше все нормально было, на тернарных операторах стало выдавать "operand types are not compatible with the operator" или "Типы операндов не совместимы с оператором."
Достает.
Можно как-то это убрать ?
Погуглил
Преобразование System.String в str
https://community.dynamics.com/ax/f/...patible/577041
https://community2.dynamics-int.com/...tor-in-ax-2012
http://www.javaear.com/question/28894455.html
Ясности не добавило.
Мне кажется это явно какой-то баг компилятора.
Так как аналогичный код написаный через if и оператор присваивания работает хорошо и ругани нет.
Для примера вот такой код из реального проекта
X++:
public static boolean validateField_MRC(Common _record, FieldId _fieldId, boolean _ignoreDataSourceLevel = false)
{
DictField dictField;
FormDataSource fds;
FormDataObject fdo;
str testStr;
container con;
boolean ret;
;
dictField = new DictField(_record.TableId, _fieldId);
fds = null; // не ругается
fds = !_ignoreDataSourceLevel ? (SysDictClass::as(_record.dataSource(), classNum(FormObjectSet))) : null; // не ругается
fds = !_ignoreDataSourceLevel ? (SysDictClass::as(_record.dataSource(), classNum(Object))) : null; // не ругается
fds = !_ignoreDataSourceLevel ? _record.dataSource() : null; // ругается
fdo = fds ? fds.object(_fieldId) : null;
ret = !(dictField.mandatory() || (fdo && fdo.mandatory())) || validateFieldIsSet_MRC(_record, _fieldId);
if (ret)
{
ret = fdo ? fdo.validate() : _record.validateField(_fieldId); // ругается - один boolean отличается от другого ?
ret = fdo ? fdo.validate() : any2int(_record.validateField(_fieldId)); // не ругается
ret = fdo ? fdo.validate() : any2enum(_record.validateField(_fieldId)); // не ругается
ret = fdo.validate(); // не ругается
ret = _record.validateField(_fieldId); // не ругается
}
testStr = conPeek(con, 1) ? conPeek(con, 2) : @""; // ругается
testStr = conPeek(con, 2); // не ругается
testStr = @""; // не ругается
return ret;
}
1. Как можно это обойти ? Неужели везде дописывать any2XXX(..) ?
2. Какие идеи почему так сделано ?
Мне пока кажется что это из-за проблем с маршаллингом X++ <---> CIL
Самый простой способ, какой нашел - юзать any2XXX() функции - так читаемость кода страдает меньше всего. Либо переделывать на if else c явным присваиванием.
Для случая классов и таблиц можно написать в Global свои методы any2Object_MRC() и any2Common_MRC(). Можно также задействовать SysDictClass::as()
X++:
// см. также Global::asObject()
static public Object any2Object_MRC(anytype _parm)
{
Object ret;
;
switch (typeOf(_parm))
{
case Types::Class:
// info(" any2Object_MRC:Class");
return _parm;
// break;
case 44: // typeOf(null)
// info(" any2Object_MRC:null of Class");
return _parm;
// break;
case Types::AnyType: // такое бывает когда дефолтное значение anyType приходит в CIL
// info(" any2Object_MRC:anyType");
return _parm;
// break;
default:
// info(" any2Object_MRC:other");
}
return ret;
}
X++:
// см. также Global::asCommon()
// и SysDictTable::as()
//
static public Common any2Common_MRC(anyType _parm)
{
;
return _parm;
}
но они нормально работают только для ненулевых ссылок. Особенно в CIL.