![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Дополнение перечисления
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 - проверка есть. Хотя тут уже могу ошибаться.