11.07.2007, 05:33 | #1 |
Участник
|
Переменные в наследнике класса
Добрый день,
Подскажите, пожалуйста, суть такой проблемы. 1. Есть класс А, в нём есть переменные глобальные a. В нём также реализованы диалог и метод К, обрабатывающий информацию с диалога. В классе А переменная a нигде не инициализируется. 2. Пишу наследник класса А, назовём его В. В этом классе перекрывал dialog, getfromdialog, validate, и метод К. Причём в getfromdialog присвоено значение переменной а. Например a = 1. 3. В методе К в наследнике (классе В) пишу отдельный код для обработки переменной a (без super(). Проблема: переменная a в классе В инициализируется и принимает значение только там в методе getfromdialog, после этого она стала null в методе К класса В и ранее присвоенное значение вообще не может использоваться. Об этом убедился путём растановки точки остановки в различных местах кода. Ещё, если та переменная a инициализируется не в наследнике В, а в основном А, то всё нормально. Можно так и решить проблему, только это мне не очень нравится, потому что мне нужно несколько наследников класса А, в каждом из них надо принимать отдельные переменные. Да и тоже хочу понять суть проблемы Работаю в AX 3.0 SP5, в трёхзвеньке. Спасибо. |
|
11.07.2007, 08:40 | #2 |
Участник
|
Сделайте навсякий случай инкрементную компиляцию классов. Если не поможет.Посмотрите в classdeclaration сохранение последних значений в классах есть? Может что-то с методами pack unpack. А точно в классе A нигде неиспользуетя переменная, может где-то подменяется?
|
|
11.07.2007, 10:15 | #3 |
Участник
|
Я уже пробовал расставить точки остановки и после этого последовательно кнопкой F8 для отслежения процессов. - dialog вызывается из класса-наследника.- getfromdialog точно вызывается из класса-наследника и на этом шаге переменной a точно присвоено значение, который указан в dialog.- После этого кнопкой F8 отслживаю стек операций. Были вызваны кучи методов системных классов. Потом, когда процесс вновь возвращается к методу класса В ( в класс А этот метод тоже есть но перекрывается в В), все глобальные переменные, присвоенные в классе А, сохраняют значением, все глобальные переменные, присвоенные в клаасе В, стали null.Вот что я не понял. Если это касается принципа наследования классов, подскажите пожалуйста.
|
|
11.07.2007, 10:28 | #4 |
SAP
|
такое бывает, правда сам не понел из-за чего, в таком слачае приходится создовать новые классы, и копировать код. lol
|
|
11.07.2007, 10:31 | #5 |
Участник
|
Он, ещё так .Но я так не думаю, потому я тоже так делал (создать новый класс с таким же принципом). Так что обязательно проблема приципиальная.
|
|
11.07.2007, 10:39 | #6 |
Участник
|
Класс выполняется на сервере или на клиенте?
Используется обычный диалог или своя форма? в методе validate переменные еще содержат значения, которые были в getFromDialog? |
|
11.07.2007, 11:11 | #7 |
Участник
|
- Класс выполняется по-моему на сервере. Об этом убедился он принимает файл \\web\c\abc.txt, но не принимает c:\abc.txt. Хотя это тот же самый файл. А вообще каким образом можно узнать место выполнения класса ?
- Метод dialog был определен в основном классе (классе А). В классе А он построен просто из dialogRunBase базового, никаких дополнительных форм нет. В классе В я перекрыл, сделал super(), потом, деактивизировал некоторые ненужные элементы и активизировал некоторые другие (активизировать с методом acitve, а не дополнил). - Метод validate тоже был определен в основном клаасе. Правда что там много чего. Для наследника класса я перекрыл без super(), выводя сразу true; |
|
11.07.2007, 11:20 | #8 |
Участник
|
как посмотреть место выполнения класса - да множество способов.
Пожалуй, самый простой - это открыть свойства класса и посмотреть что там написано. в 2 из 3 возможных вариантов сразу будет ясно (Server или Client). Если же установлено calledFrom, надо уже смотреть другими способами. Дебаггер показывает иконку соответствующую в стеке операций. (Сервер или клиент). Можно посмотреть там (поставив точку останова в нужном методе) Из кода - есть метод Global::isRunningOnServer - возвращает true, если метод выполняется на сервере. Думаю, есть и масса других способов - к примеру, вывести winApi::getComputerName() и посмотреть, клиентская машина это или сервер По поводу проблемы - я бы еще раз проделал все, что советовал miklenew - конкретно проверил бы, что метод pack запаковывает все те переменные, которые далее использоваться будут. (переменная а) |
|
11.07.2007, 11:57 | #9 |
Участник
|
Спасибо. Пробовал.- Метод класса В, в котором было присвоено значение переменной a, выполняется на клиенте (моей машине).- Метод класса В, который обрабатывает переменную a, выполняется на сервере.- Я тоже раньше проделал инкрементную компиляцию. pack() вызывается из класса А (без перекрытия), он действительно упаковывает переменную a. Переменная a теряет свое значение (станет null) только долго после выполнения pack() - в одном из системных классов).
|
|
11.07.2007, 12:15 | #10 |
MCTS
|
А как в классе В реализованы метод pack() unpack() ?
Такое впечатление что переменная а не внесена в контейнер с которым работают эти методы.
__________________
С уважением, Павел Цераниди. На пути к совершенству нет конца. Каждое новое достижение является отправной точкой для следующего крупного шага. |
|
11.07.2007, 12:22 | #11 |
Участник
|
В классе В нет методов pack() и unpack(), оба метода наследуются от основного класса А.Дело в том, что переменные a была объявлена в классе А как глобальная. В макросе CurrentList в классе А тоже есть переменная a.
|
|
11.07.2007, 13:54 | #12 |
Участник
|
Выложите два этих класса. И название метода и переменной которая вас интересует. Не а, в, а как они в живую называются.
|
|
11.07.2007, 14:10 | #13 |
Участник
|
Вот эти 2 класса.
Класс А - это LedgerInAccountStatement; Класс В - это LedgerInAccountStatement_AbsolutBank; Переменная a - это filename |
|
11.07.2007, 14:27 | #14 |
Участник
|
Я бы вам посоветовал пользовательский кэш почистить.
А лучше сменить номер версии (CurrentVersion) в классе LedgerInAccountStatement и сделать для него инкрементную компиляцию
__________________
Axapta v.3.0 sp5 kr2 |
|
11.07.2007, 14:33 | #15 |
Участник
|
Да пользовательский кэш почистил в первую очередь, только после этого стал разобраться что за проблема А вот второй совет не совсем понял. Что именно даёт изменение номера версии при инкрементной компиляции ?
|
|
11.07.2007, 14:36 | #16 |
Участник
|
Изменение номера версии приведет к тому, что метод unpack вернет false
(это сродни очистки данных пользователя по этому классу) а для того, чтобы это изменение действительно прошло, необходимо сделать инкрементную компиляцию. |
|
11.07.2007, 14:47 | #17 |
Участник
|
|
|
11.07.2007, 15:04 | #18 |
Участник
|
М..да. Действительно помогло. Большое спасибо
Определил новый локальный макрос для наследника В #CurrentList и #CurrentVesion. Потом перекрыл методы pack() и unpack(). Там ничего нового нет, просто удалил super() и скопировал туда то, что и есть в основном классе А. Очистил кэш и всё сработал . Теперь после решения проблемы тоже интересно что за проблема была. Раньше я же пробовал инкрементную компиляцию. Вижу что после выполнения классом В метода pack() из основного класса А всё-таки переменная a сохраняет значение. Только после этого, когда стек операций зашёл глубже в системные классы, а теряет присвоенное значение. |
|
11.07.2007, 15:04 | #19 |
Пенсионер
|
Попробуйте изменить имя переменной с filename на какое нибудь другое.
__________________
Законы природы еще никто не отменял! А еще у меня растет 2 внучки!!! Кому интересно подробности тут: http://www.baby-shine.com/ |
|
11.07.2007, 15:06 | #20 |
Участник
|
Это не помогает. Я тоже попробовал создал локальную переменную для замены глобальной переменной а в наследнике. Всё равно происходит то же самое. Значит проблема может именно где в вызове pack() и unpack() из основного класса.
|
|