Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Unit X was compiled with a different version of Y


Автор: XperT 24.1.2014, 12:53
Помогите решить проблему: "Unit MyClasses was compiled with a different version of AppSettings.Z". Выскакивает при изменениях в классе AppSettings.Z, помогает только ребилд проекта, но это долго каждый раз такое делать.

Точно помню, что уже сталкивался с этой проблемой и решил её, но как я это тогда сделал не могу вспомнить.

Автор: northener 25.1.2014, 01:34
Недостаточно информации. Эта "проблема" имеет массу корней. Который из них вы затронули не известно. Например о каких изменениях в классе AppSettings.Z идёт речь?

Автор: XperT 27.1.2014, 11:45
В общем так. Есть модуль AppSettings, в котором есть класс TAppSettings, в котором в свою очередь есть переменная класса TProgramFolders. Так вот изменения в класс TProgramFolders (например добавление новых констант и методов класс) приводят к появлению таких сообщений. Для большей ясности привожу кусок кода программы.

Код

unit AppSettings;

TProgramFolders = class
private
    FExeDir : String;

    const cCore = 'Core\';
    const cProjects = 'Projects\';
    const cTemp = 'Temp\';

    function FGetTempDir():string;
    function FGetCoreDir():string;
    function FGetProjectsDir():string;
public
    constructor Create(ExeDir : String);

    property Exe: string read FExeDir;
    property Temp: string read FGetTempDir;
    property Core: string read FGetCoreDir;
    property Projects: string read FGetProjectsDir;
end;

TAppSettings = class
private
    FDIR : TProgramFolders;
    ...
public
    ...
    property DIR : TProgramFolders read FDIR;
end;

var
    Z : TAppSettings;

implementation

...

Автор: XperT 31.1.2014, 10:50
Апну тему. Может кто-то подскажет где почитать? Для меня например не понятно, почему IDE сама не контролирует какие модули нужно перекомпилировать.

Автор: XperT 1.2.2014, 17:07
В общем удалось найти причину и устранить проблему. В моём случае проблема была из-за такой структуры файлов:

Модуль A: ссылается на модуль C (в interface)
Модуль B: ссылается на модуль C (в interface) и на модуль А (в implementation)
Модуль C: ссылается на модуль А (в implementation)

Переделал немного структуру модулей таким образом, чтобы уменьшить количество перекрестных ссылок и проблема исчезла.

Автор: Poseidon 2.2.2014, 02:11
Когда А ссылается на С, а С ссылается на А, это говорит об ошибке проектирования кода. 

Автор: XperT 2.2.2014, 15:23
Цитата(Poseidon @ 2.2.2014,  02:11)
Когда А ссылается на С, а С ссылается на А, это говорит об ошибке проектирования кода.

Ок, тогда подскажите как сделать в такой ситуации: есть модуль с классом А, который генерирует кнопки в меню программе по клике на которые должна открываться определенная форма Б. Один из методов модуля А - это обработчик на клик по кнопке, в котором вызывается форма Б, а это значит, что необходимо добавить в зависимость модуль формы Б. В самой форме Б используется объект класса из модуля А для чтения настроек и генерирования правильных контролов и обработчикок.

Получается, что А ссылается на Б, а Б ссылается на А. Какой выход из подобной ситуации без допуска ошибок по проектированию? Создавать в модуле Б свой класс с настройками, в которые будут копироваться необходимые значения из модуля А? Ну так это дублирования данных, что имхо еще хуже.

Единственный вариант, который я вижу - это передавать в конструктор класса А делегат на создание формы Б, но в таком случае сильно ухудшается чтение кода, так как он получается размазан по 3 модулям.


Очень сильно не хватает аналога сишным заголовочным файлам, тогда бы эта проблема исчезла сама собой. Там проще проектировать за счет того, что объявления и реализацию можно разнести по модулям.

Автор: Poseidon 2.2.2014, 16:23
Цитата(XperT @  2.2.2014,  15:23 Найти цитируемый пост)
есть модуль с классом А, который генерирует кнопки в меню программе по клике на которые должна открываться определенная форма Б. Один из методов модуля А - это обработчик на клик по кнопке, в котором вызывается форма Б, а это значит, что необходимо добавить в зависимость модуль формы Б. В самой форме Б используется объект класса из модуля А для чтения настроек и генерирования правильных контролов и обработчикок.
Если я правильно понял, в А у нас генерация кнопок и реакция на их нажатие. В Б у нас описана форма, на которой генерируются эти кнопки. Очевидно, что Б должен знать об А, но вот А совсем не должен знать о Б. Если приведете пример конкретного кода, то объясню на примере.


Цитата(XperT @  2.2.2014,  15:23 Найти цитируемый пост)
Один из методов модуля А - это обработчик на клик по кнопке, в котором вызывается форма Б

Цитата(XperT @  2.2.2014,  15:23 Найти цитируемый пост)
В самой форме Б используется объект класса из модуля А

Уже это говорит о не правильном проектировании. Если в Б используется объект из А, то Б зависит от А. Описывать при этом в А обработчик события из Б как-то не логично.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)