-
Здравствуйте! У меня есть набор команд, которые закодированы числами. Часть команд является базовой, а часть может изменяться. Я бы хотел описать в одном модуле перечисление с базовым набором команд, а в других модулях иметь возможность расширять его. Примерно так:
base.pas
TCommandTypes =
(
mtDeviceError = $FF,
mtVersionInfoRequest = $00,
mtVersionInfoAnswer = $80,
);
special.pas
TCommandTypes =
(
mtOperationModeRequest = $01,
mtOperationModeAnswer = $81,
mtImpedanceMeasurmentStartRequest = $02,
mtMeasurmentStartAnswer = $82,
...
);
Такое дополнение перечислений хочется сделать для того, что бы в базовом модуле создать набор функций, которые бы принимали TCommandTypes и работали бы как для команд из базового модуля, так и для команд из любого другого и вместе с тем работала бы проверка времени компиляции. Понятно, что если я поступлю так как в примере, то базовый набор команд будет просто закрыт и ничего не получится. Как можно добиться желаемого?
-
одно полное длинное перечисление. там, где хочется контроль по ограниченному перечню - ассерт
-
> Kolan © (16.03.09 11:32)
Чем простые константы не устроили?
-
Интересно, откуда возникло такое желание, ведь суть перечислений - это именно постоянность
-
>Чем простые константы не устроили? Из всех вариантов этот мне нравится больше всего, но плохо, что в методах придется писать Foo(Command: Integer) , а не Foo(Command: TCommandTypes) . MsGuns, желание возникло так как сабжевые команды — это команды их протокола разных устройств. Часть таких команд базовая и есть во всех устройствах, а другая часть у каждого устройства своя. >одно полное длинное перечисление. Это невозможно сделать, я не знаю какие команды будут у устройств, которые появятся, скажем, в следующем году.
-
> Kolan © (16.03.09 12:40) [4]
И в чем проблемы? Type
TCommandType=type Integer;
Const
mtDeviceError:TCommandType = $FF
-
Это невозможно сделать, я не знаю какие команды будут у устройств, которые появятся, скажем, в следующем году.
Тогда стоит подумать вообще о логичности выбора перечисления как нудного типа. Хотя не вижу препятствий. У меня тодже команды и тоже перечисления, причем даже без уточнения значений. Перечень команд постоянно из месяца в месяц растет. И ничему этот рост не мешает.
-
Palladin, отлично! Проверки типа нет, но подсказка при вызове функции выводится вполне понятная. Я думаю путаницы не возникнет, поэтому считаю, что ответ получил — благодарю.
-
> Проверки типа нет,
ЕМНИП, когда type Integer - проверка есть. Хотя тут уже могу ошибаться.
-
Ega, я проверил:
TForm2 = class(TForm)
...
public
procedure foo(command: TCommandType);
end;
procedure TForm2.foo(command: TCommandType);
begin
ShowMessage(IntToStr(command));
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
foo(1);
end; Единичку показал. Так что проверки нет. Но я думаю, что правильный префикс и подсказка при вызове метода поможет избежать проблем.
-
Проверка производится только когда переменная передаётся в функцию через var. В этом случае integer и type integer трактуются как разные типы.
-
Возникла проблема в операторе 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. Как объяснить компилятору, что это константа?
-
зачем все это? иметь перечисление TEnum = (one,two,three) и массив array[TEnum] (и то если важно десятичное значение).
и все.
Для алгоритма значение не нужно, ну а девайс посылать прямо значения енума - не очень логично.
-
Медвежонок Пятачок, я не понимаю что вы предлагаете. Попробую объяснить еще раз.Мне хочется написать метод Foo(Command: TCommandType); . Command — это некоторое число которому надо дать осмысленное имя. Проблема в том, что с одной стороны в одном модуле число $90 может означать одно, а в другом другое и программист должен видеть и понимать что от него хотят и что он передал, а с другой Foo должно работать с любым переданным числом. Причем тут массив — не ясно. >...ну а девайс посылать прямо значения енума - не очень логично. Почему не логично? Я думаю, что запись SendCommand(1); гораздо хуже чем запись SendCommand(ctBlowUp); . Вы так не считаете?
-
Причем тут массив — не ясно.
TEnum = (one,two,three)
все ясно и понятно. элементы перечисления с осмысленными именами. и кейс доволен.
-
Медвежонок Пятачок, как теперь в другом модуле добавить в TEnum еще four и five?
-
если в другом модуле, то это будет уже другой тип
-
Тогда мне придется писать несколько функций для обработки этих констант, а это плохое решение.
-
я честно говоря не понимаю, почему расширение базового перечисления может чем-то помешать базовому модулю.
-
> Как объяснить компилятору, что это константа? >
Это "типизированная" константа. А её значение можно изменить в рантайме. И как тут быть компилятору?
|