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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 20.08.2024, 17:17   #1  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,940 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Как гарантированно проверить что объект = null
Привет.

При проверке на null бывают интересные случаи.
Например, добавили контрол на форме
X++:
formStringControl = element.design().addControl(FormControlType::String, "TestControl");
затем удалили
X++:
element.design().removeControl(formStringControl.id());
После этого отладчик показывает в окне просмотра значений, что переменная formStringControl - равна null

Если же в коде проверять
X++:
if (formStringControl)
то считает что ссылка ненулевая.
Но попытка вызвать на ней любой метод приводит к исключению.

Как можно предупредить такие случаи и понять что объект за ссылкой уже убит и она невалидна ? Ведь отладчик как-то это понимает при отображении значения в окне просмотра значений переменных.

Есть обходной способ - не хранить ссылки на контролы, а запоминать их идентификаторы и по мере надобности каждый раз доставать контрол по идентификатору.
X++:
formStringControl = element.design().addControl(FormControlType::String, "TestControl");
id = formStringControl.id();
...
element.design().removeControl(id);
...
if (id) 
{
    formStringControl  = element.design().control(id);
    if (formStringControl) // безопасная проверка - точно можно понять контрол еще жив или нет
    ...
}
Но ради понимания как там внутри все устроено, может можно все таки как-то безопасно понять жив объект за ссылкой или уже порушен (можно хоть один метод на нем безопасно вызвать или нет). Отладчик то как-то это понимает. Значит и мы можем.
Старый 20.08.2024, 18:15   #2  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
В методе SysClassWizard.frameworkInitGroups() в связке с удалением объекту контрола сразу же присваивается значение null.
Думаю - так и надо сразу делать.
X++:
    this.design().removeControl(formGroupControl.id());
    formGroupControl = null;
__________________
// no comments
За это сообщение автора поблагодарили: Logger (3).
Старый 20.08.2024, 18:49   #3  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,940 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от dech Посмотреть сообщение
В методе SysClassWizard.frameworkInitGroups() в связке с удалением объекту контрола сразу же присваивается значение null.
Думаю - так и надо сразу делать.
X++:
    this.design().removeControl(formGroupControl.id());
    formGroupControl = null;
Логично.
Для описанного случая подходит.

Но вопрос немного шире. Как проверить валидность ссылки в целом. Бывают и другие ситуации.
Старый 21.08.2024, 07:24   #4  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
По сути, вы сами всё расписали. Надо заново найти контрол по id.
X++:
    formStringControl  = element.design().control(id);
    if (formStringControl) // безопасная проверка - точно можно понять контрол еще жив или нет
Если же вы не хотите терять связь через локальную переменную, то кроме явного присваивания null, я других вариантов не вижу. Пути сборщика мусора неисповедимы.
Попробуем углубиться в детали.
У вас переменная ссылается на объект, контрол, который пока что существует. Метод removeControl() находит объект по id и удаляет его из памяти. Будет ли метод обновлять все ссылки на удаленный объект? Думаю нет. Соответственно, у вас останется ссылка на некую область в памяти, обращение к которой даст сбой. Однако проверка на неравенство null завершится успешно.
Плюс, я думаю, что дебаггер немного доработан с тем, чтобы не показывать тот фарш, который может отобразить переменная, если она ссылается не туда, куда надо.
__________________
// no comments
Старый 22.08.2024, 06:16   #5  
Pandasama is offline
Pandasama
Участник
 
457 / 134 (5) +++++
Регистрация: 11.08.2014
Адрес: Барнаул
Цитата:
Сообщение от Logger Посмотреть сообщение
Если же в коде проверять
X++:
if (formStringControl)
то считает что ссылка ненулевая.
А если явно проверить formStringControl is null или formStringControl == null ?
Старый 22.08.2024, 10:02   #6  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,940 / 3229 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
то же самое

Также не работает
X++:
classIdGet
typeOf(formStringControl ) == 44
ClrInterop::isNull
и.т.п.
Старый 23.08.2024, 00:16   #7  
Товарищ ♂uatr is offline
Товарищ ♂uatr
Участник
Аватар для Товарищ ♂uatr
MCBMSS
 
297 / 866 (29) +++++++
Регистрация: 23.10.2012
Привет.
За все возможные object'ы не скажу, но что касается formControl'ов здесь можно использовать hWnd. Соответственно решением данной проблемы будет проверка его на действительность.
isWindow у WinApi, легко выявляет данную проблему:
X++:
FormControl c;
int hWnd;
;

c = element.design().addControl(FormControlType::Button, 'tst');
hwnd = c.hWnd();
info(int2str(WinApi::isWindow(hwnd))); // 1
element.design().removeControl(c.id());
info(int2str(WinApi::isWindow(hwnd))); // 0
Теперь время жирнющей ремарки - hWnd могут быть переиспользованы.
Шанс, как обычно, стремится к 0 у единичного юзера и возрастает с увеличением их количества.
Стоит ли подстраховываться?...Зависит от того какую задачу решаете.

Последний раз редактировалось Товарищ ♂uatr; 23.08.2024 в 00:40.
За это сообщение автора поблагодарили: Logger (5).
Теги
null

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Быстродействие метда TaxParameters::find Ace of Database DAX: Программирование 7 01.06.2017 11:46
Ошибка при синхронизации Базы данных Art_Tanis DAX: Администрирование 1 24.12.2014 09:20
Проверить переменную на null PMS DAX: Программирование 16 26.09.2013 14:18
Real Data Type - No of decimals Yprit DAX: Программирование 10 30.03.2009 12:17
C# and AX Development: Using the COM Business Connector in C#, the easy way (AX/Axapta) Blog bot DAX Blogs 0 15.12.2007 20:35

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

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

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