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

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

Проверка принадлежности перечислимому типу. [D2005, XP]


TeaNick ©   (2011-11-18 13:08:00) 

Есть свой тип

TObjType = (otUnknown,otHeader,otBind);

Как проверить переменную на принадлежность этому типу

Что-то типа var1 is TObjType.

Можно конечно

var1 in [otUnknown,otHeader,otBind] но это довольно громоздко.


TeaNick   (2011-11-18 15:37:00) [1]

Согласен. Хватит извращений на сегодня.

  if not (VNode.ObjType in [Low(TObjType)..High(TObjType)]) then
  raise Exception.Create('load error!');


Всем спасибо.


Dennis I. Komarov   (2011-11-18 15:18:00) [2]


> немного поизвращенски, но работает

почему "немного"?


Сергей М.   (2011-11-18 15:03:00) [3]

> немного поизвращенски

Эт точно)
Вот обязательно нужно выковыривать из недр RTTI строки, вместо того чтобы сделать простейшую проверку [9]


Dimka Maslov   (2011-11-18 14:41:00) [4]


> Variant?


Вариант это способ организации хранения данных. Сама переменная как имела тип вариант, так и будет его иметь.


TeaNick   (2011-11-18 14:36:00) [5]

Всем спасибо за варианты.
Придумал еще такое решение

uses TypInfo;

....................

var i:integer;
    s:string;

............
    read(F,VNode);

     i:=integer(VNode.ObjType);
     s:=GetEnumName(TypeInfo(TObjType),i);
     if s=EmptyStr then
     raise
       Exception.Create('load error!');

немного поизвращенски, но работает

Экспериментальным путем установлено что

     if GetEnumName(TypeInfo(TObjType),integer(VNode.ObjType))=EmptyStr then
     raise
       Exception.Create('load error!');

работать не хочет и при включенной оптимизации и без


Медвежонок Пятачок   (2011-11-18 14:04:00) [6]

>[11]
если бы еще вспомнить что (по дефолту) перечислимое это тупо физически тупо байт.


OW   (2011-11-18 14:03:00) [7]


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

TObjType = (otUnknown =3, otHeader =5, otBind=65 );
testvalue = 57
3<57<65
но мимо


Anatoly Podgoretsky   (2011-11-18 14:01:00) [8]


> Так вот надо проверить VNode.ObjType на принадлежность TObjType,
>  иначе
> неверный формат файла.

В файле уже нет пользовательских типов, там только значение допустимые или нет.


OW   (2011-11-18 14:01:00) [9]

type
 TObjType = (otUnknown, otHeader, otBind );
 TSETObjType = Set of TObjType;
var
 v1 : TObjType;
 v2 : TSETObjType;
 v3 : integer;
begin
 v2 := [otUnknown] + [otHeader] + [otBind];
 v1 := otUnknown;
 if v1 in v2 then ShowMessage( 'v1 in v2');
 v3 := 5;
 if TObjType(v3) in v2 then ShowMessage( 'v3 := 5 in v2');
 v3 := 2;
 if TObjType(v3) in v2 then ShowMessage( 'v3 := 2 in v2');

или
TObjType = (otUnknown = 34, otHeader=45, otBind=85 );


Медвежонок Пятачок   (2011-11-18 13:56:00) [10]

в бинарном файле как целочисленные

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


Медвежонок Пятачок   (2011-11-18 13:54:00) [11]

0 <= ord(x) <= otBind


TeaNick   (2011-11-18 13:51:00) [12]

Не все так просто

Есть

TObjType = (otUnknown,otHeader,otBind);

TvNode = packed record
   Level:integer;
   ObjType:TObjType;
end;

есть
 F:file of TvNode;
 VNode:TvNode;

 while not eof(F) do begin
     read(F,VNode);
 .......
Так вот надо проверить VNode.ObjType на принадлежность TObjType, иначе
неверный формат файла.

Само чтение никакого исключения не вызывает, а поле ObjType совершенно спокойно читается из бинарного файла как целочисленное.
В вочлисте VNode.ObjType просто пишет (out of bound) - 47 или любой другое число (больше 2-х).
Логично что перечислимые типы сохряняются в бинарном файле как целочисленные, но вот такая проблема при чтении.


Медвежонок Пятачок   (2011-11-18 13:48:00) [13]

какая изящная ересь.


OW   (2011-11-18 13:37:00) [14]

type
 TObjType = (otUnknown,otHeader,otBind);
 TSETObjType = Set of TObjType;
var
 v1 : TObjType;
 v2 : TSETObjType;
begin
 v2 := [otUnknown] + [otHeader] + [otBind];
 v1 := otUnknown;
 if v1 in v2 then ShowMessage( '');

изящнее, наверное, никак в общем случае
если только тип будет паблишет, и для него получится RTTI взять


Медвежонок Пятачок   (2011-11-18 13:36:00) [15]

var1 in [otUnknown,otHeader,otBind] но это довольно громоздко.
это не громоздко.

но не отвечает на поставленный вопрос.


Медвежонок Пятачок   (2011-11-18 13:34:00) [16]

и вариант тоже


Омлет   (2011-11-18 13:29:00) [17]


> Dimka Maslov ©   (18.11.11 13:17) [2]
> У нас тут дельфи. Тип переменной указывается строго при
> её объявлении и не может быть изменён.

Variant?


Dimka Maslov   (2011-11-18 13:17:00) [18]

У нас тут дельфи. Тип переменной указывается строго при её объявлении и не может быть изменён.


Сергей М.   (2011-11-18 13:16:00) [19]


> Как проверить переменную на принадлежность этому типу


Если ты объявил переменную var1: TObjType, то как она может иметь тип отличный от TObjType ?


> Можно конечно
>
> var1 in [otUnknown,otHeader,otBind]


Для этого делают еще один тип - множественный.

TObjTypeSet = set of TObjType;

И вот теперь :

var
MyObjTypeSet: TObjTypeSet;
var1: TObjType;
..
if var1 in MyObjTypeSet then ..


Наверх

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