Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2010.02.14;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.005 c
2-1260867479
noob_one
2009-12-15 11:57
2010.02.14
Как программно скопировать все данные из DBGridEh в буфер обмена?


6-1212475055
ketovchanin
2008-06-03 10:37
2010.02.14
Proxy-Authorization


2-1260787419
noob_one
2009-12-14 13:43
2010.02.14
Как узнать что в Clientdataset загружен другой набор данных?


15-1260394794
kyn66
2009-12-10 00:39
2010.02.14
Avast тормозит загрузку таблиц


15-1260309385
GanibalLector
2009-12-09 00:56
2010.02.14
PortMon





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский