В D365FO семейство классов RAssetProposal очень "занятно" распаковывает параметры в unpack(), из-за чего не так просто добавлять в это семейство новые параметры для сохранения в pack()/unpack().
Коллега недавно наткнулся на проблему, пытаясь применить к этому семейству
рекомендации по расширению наследников RunBase. В рекомендациях говорится, что в pack() вашего класса-расширения нужно написать примерено так:
X++:
public container pack()
{
container packedClass = next pack();
return SysPackExtensions::appendExtension(packedClass, classStr(MySysUserLogCleanup_Extension), this.myPack());
}
При этом - внимание! - в конец общего контейнера допишется еще один элемент-контейнер с параметрами вашего расширения. Если расширений несколько, то, вероятно, допишется не один элемент, а несколько. В unpack() же класса-расширения вам надо написать примерно вот так:
X++:
public boolean unpack(container _packedClass)
{
boolean result = next unpack(_packedClass);
if (result)
{
container myState = SysPackExtensions::findExtension(_packedClass, classStr(MySysUserLogCleanup_Extension));
result = this.myUnpack(myState); //Also unpack the extension
}
return result;
}
Но в случае RAssetProposal следование официальной инструкции приводит к ошибке времени выполнения в расширяемом классе: невозможно инициализировать queryRun из контейнера.
Вот как бы вы работали с queryRun в pack/unpack? Обычно это выглядит так:
X++:
public container pack()
{
return [#CurrentVersion, #CurrentList, queryRun.pack()];
}
X++:
public boolean unpack(container _packedClass)
{
Version version = RunBase::getVersion(_packedClass);
boolean ret = true;
switch (version)
{
case #CurrentVersion :
container packedQuery;
[version, #CurrentList, packedQuery] = _packedClass;
if (SysQuery::isPackedOk(packedQuery))
// ...
Обратите внимание, что конструкция вида
X++:
[version, #CurrentList, packedQuery] = _packedClass;
симметрична конструкции
X++:
return [#CurrentVersion, #CurrentList, queryRun.pack()];
она позволяет безболезненно отбросить все лишние элементы в конце контейнера _packedClass и взять своё строго с тех позиций, какие получились в вашем pack().
Но локализаторы же хитрее всех, поэтому они считают, что их запакованный queryRun всегда идет последним, и пишут вот что:
X++:
public boolean unpack(container packedClass)
{
Integer version = conPeek(packedClass,1);
container packedQuery = conPeek(packedClass, conLen(packedClass));
Поскольку наш контейнер стал длиннее за счет параметров класса-расширения, то вместо запакованного queryRun локализаторы, разумеется, получают левый контейнер и валятся на нем в ошибку времени выполнения.