Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Дополнение перечисления


Страницы:   1 2

Kolan ©   (2009-03-16 11:32:00) 

Здравствуйте!

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

Примерно так:

base.pas

TCommandTypes =
 (
   mtDeviceError = $FF,
   mtVersionInfoRequest = $00,
   mtVersionInfoAnswer = $80,  
 );



special.pas

TCommandTypes =
 (
   mtOperationModeRequest = $01,
   mtOperationModeAnswer = $81,
   mtImpedanceMeasurmentStartRequest = $02,
   mtMeasurmentStartAnswer = $82,
...
 );


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

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

Как можно добиться желаемого?


Медвежонок Пятачок   (2009-03-19 10:51:00) [1]

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

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


Kolan   (2009-03-19 10:12:00) [2]


> Это если понятие "модуль" равно понятию "длл".

Понятие модуль равно понятию модуля (unit).


> Растущее и удлинняющееся от версии к версии программы.

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


> А если всё внутри одного проекта, то, имхо, только константы
> с префиксами.

Так и поступил.


> Так что сам виноват, очкарик, что вляпался. :)

Давненько я тут не был. :)

Вопрос считаю закрытым, благодарю за обсуждение.


SPeller   (2009-03-18 07:37:00) [3]

А если всё внутри одного проекта, то, имхо, только константы с префиксами. Если неохота юзать переменные константы.


SPeller   (2009-03-18 07:36:00) [4]

Это если понятие "модуль" равно понятию "длл".


SPeller   (2009-03-18 07:34:00) [5]


> как теперь в другом модуле добавить в TEnum еще four и five?

Очень просто. Руками. Берешь и добавляешь. В старом модуле ничего не поломается если там нет массивов на основе твоего старого перечисления (array[TEnum]) и все твои if и case предусматривают возможность появления значения вне рамок перечисления, определенных на этапе компиляции.


Германн   (2009-03-18 00:07:00) [6]


> Kolan ©   (17.03.09 10:33) [20]
>
> Герман, если спросить меня, то я бы не делал констант, которые
> могут изменяться :).

Это было введено в Паскаль очень давно. И поменьше, но тоже давно, объявлено Борландом как оставленное для обратной совместимости, и что в новых проектах использование типизированных констант не рекомендуется!
Так что сам виноват, очкарик, что вляпался. :)


Медвежонок Пятачок   (2009-03-17 17:58:00) [7]

Вот поэтому я и не предлагал и не предлагаю "расширять" перечисление в других модулях.
Одно перечисление на все про все.
Растущее и удлинняющееся от версии к версии программы.


Kolan   (2009-03-17 10:33:00) [8]

Герман, если спросить меня, то я бы не делал констант, которые могут изменяться :).
Пока просто убрал тип, и сделал документацию, но лучше бы код сам себя документировал.

Медвежонок Пятачок, потому что метод в базовом модуле, который принимает тип TCommandType из этого же базового модуля не сможет принять тип TCommandType из другого модуля, так как это разные типы.


Германн   (2009-03-16 17:00:00) [9]


> Как объяснить компилятору, что это константа?
>

Это "типизированная" константа. А её значение можно изменить в рантайме. И как тут быть компилятору?


Медвежонок Пятачок   (2009-03-16 16:39:00) [10]

я честно говоря не понимаю, почему расширение базового перечисления может чем-то помешать базовому модулю.


Kolan   (2009-03-16 16:37:00) [11]

Тогда мне придется писать несколько функций для обработки этих констант, а это плохое решение.


Медвежонок Пятачок   (2009-03-16 16:32:00) [12]

если в другом модуле, то это будет уже другой тип


Kolan   (2009-03-16 15:40:00) [13]

Медвежонок Пятачок, как теперь в другом модуле добавить в TEnum еще four и five?


Медвежонок Пятачок   (2009-03-16 14:57:00) [14]

Причем тут массив — не ясно.

TEnum = (one,two,three)

все ясно и понятно. элементы перечисления с осмысленными именами.
и кейс доволен.


Kolan   (2009-03-16 14:37:00) [15]

Медвежонок Пятачок, я не понимаю что вы предлагаете.

Попробую объяснить еще раз.
Мне хочется написать метод Foo(Command: TCommandType);. Command — это некоторое число которому надо дать осмысленное имя.

Проблема в том, что с одной стороны в одном модуле число $90может означать одно, а в другом другое и программист должен видеть и понимать что от него хотят и что он передал, а с другой Fooдолжно работать с любым переданным числом.

Причем тут массив — не ясно.

>...ну а девайс посылать прямо значения енума - не очень логично.
Почему не логично? Я думаю, что запись SendCommand(1);гораздо хуже чем запись   SendCommand(ctBlowUp);. Вы так не считаете?


Медвежонок Пятачок   (2009-03-16 14:08:00) [16]

зачем все это?
иметь перечисление TEnum = (one,two,three)
и массив array[TEnum] (и то если важно десятичное значение).

и все.

Для алгоритма значение не нужно, ну а девайс посылать прямо значения енума - не очень логично.


Kolan   (2009-03-16 13:50:00) [17]

Возникла проблема в операторе case.

Если объявлять константы так:

type
 TCommandType = type Integer;
const

 ctDeviceError: TCommandType = $FF;
...


И использовать так:

function TCustomFreGrafDeviceProtocol.DefineCommandType(
 Command: TCommandType): string;
begin
 case Command of
   ctDeviceError:
     Result := rsDeviceError;
...


То компилятор говорит, что: Constant expression expectedв строке с ctDeviceError:. Если убрать из объявления констант TCommandType, то есть написать просто ctDeviceError = $FF;, то скомпилировать удается. Но в этом случае получается, что константы не связаны с типом TCommandType.

Как объяснить компилятору, что это константа?


Dimka Maslov   (2009-03-16 13:43:00) [18]

Проверка производится только когда переменная передаётся в функцию через var. В этом случае integer и type integer трактуются как разные типы.


Kolan   (2009-03-16 13:38:00) [19]

Ega, я проверил:

 TForm2 = class(TForm)
...
 public
   { Public declarations }
   procedure foo(command: TCommandType);
 end;

procedure TForm2.foo(command: TCommandType);
begin
 ShowMessage(IntToStr(command));
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
 foo(1);
end;


Единичку показал. Так что проверки нет. Но я думаю, что правильный префикс и подсказка при вызове метода поможет избежать проблем.


Ega23   (2009-03-16 13:08:00) [20]


> Проверки типа нет,


ЕМНИП, когда type Integer - проверка есть. Хотя тут уже могу ошибаться.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо