Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.02.14;
Скачать: CL | DM;

Вниз

Дополнение перечисления   Найти похожие ветки 

 
Kolan ©   (2009-03-16 11:32) [0]

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

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

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

base.pas

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



special.pas

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


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

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

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


 
Медвежонок Пятачок ©   (2009-03-16 11:36) [1]

одно полное длинное перечисление.
там, где хочется контроль по ограниченному перечню - ассерт


 
Palladin ©   (2009-03-16 11:52) [2]


> Kolan ©   (16.03.09 11:32) 

Чем простые константы не устроили?


 
MsGuns ©   (2009-03-16 11:58) [3]

Интересно, откуда возникло такое желание, ведь суть перечислений - это именно постоянность


 
Kolan ©   (2009-03-16 12:40) [4]

>Чем простые константы не устроили?

Из всех вариантов этот мне нравится больше всего, но плохо, что в методах придется писать Foo(Command: Integer), а не Foo(Command: TCommandTypes).

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

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


 
Palladin ©   (2009-03-16 12:50) [5]


> Kolan ©   (16.03.09 12:40) [4]

И в чем проблемы?

Type
TCommandType=type Integer;

Const
mtDeviceError:TCommandType = $FF


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

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

Тогда стоит подумать вообще о логичности выбора перечисления как нудного типа.
Хотя не вижу препятствий.
У меня тодже команды и тоже перечисления, причем даже без уточнения значений. Перечень команд постоянно из месяца в месяц растет.
И ничему этот рост не мешает.


 
Kolan ©   (2009-03-16 12:59) [7]

Palladin, отлично! Проверки типа нет, но подсказка при вызове функции выводится вполне понятная. Я думаю путаницы не возникнет, поэтому считаю, что ответ получил — благодарю.


 
Ega23 ©   (2009-03-16 13:08) [8]


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


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


 
Kolan ©   (2009-03-16 13:38) [9]

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;


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


 
Dimka Maslov ©   (2009-03-16 13:43) [10]

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


 
Kolan ©   (2009-03-16 13:50) [11]

Возникла проблема в операторе 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.

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


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

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

и все.

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


 
Kolan ©   (2009-03-16 14:37) [13]

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

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

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

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

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


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

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

TEnum = (one,two,three)

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


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

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


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

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


 
Kolan ©   (2009-03-16 16:37) [17]

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


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

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


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


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

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


 
Kolan ©   (2009-03-17 10:33) [20]

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

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


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

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


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


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

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


 
SPeller ©   (2009-03-18 07:34) [23]


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

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


 
SPeller ©   (2009-03-18 07:36) [24]

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


 
SPeller ©   (2009-03-18 07:37) [25]

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


 
Kolan ©   (2009-03-19 10:12) [26]


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

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


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

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


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

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


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

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

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


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

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

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



Страницы: 1 вся ветка

Текущий архив: 2010.02.14;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.01 c
15-1260119974
TUser
2009-12-06 20:19
2010.02.14
Непятничная задача


1-1237982706
Eraser
2009-03-25 15:05
2010.02.14
TListView и экшены


4-1229006142
ZiZiTop
2008-12-11 17:35
2010.02.14
Как разговаритвать со звуковой под WinNT


2-1260513442
Xmen
2009-12-11 09:37
2010.02.14
проблема в сохранение в базе


15-1259621251
Германн
2009-12-01 01:47
2010.02.14
А есть ли тут "Мастера ПИД регуляторов"?