Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 12.05.2023, 17:51
zhirnov.ilya.lvovich zhirnov.ilya.lvovich вне форума
Прохожий
 
Регистрация: 14.02.2023
Сообщения: 4
Версия Delphi: Delphi 10.4
Репутация: 10
Вопрос Пренадлежит ли значение перечислимому типу?

Коллеги, есть код:
Код:
type
  TMyList = (mlOne = 1, mlFive = 5);
var
  iTmp: integer;

...
  iTmp := 2;
  var bFind := False;
  for var ml := Low(TMyList) to High(TMyList) - 1 do
  begin
    bFind := ord(ml) = iTmp;
    if bFind then
      Break;
  end;

вот вопрос какого ляда bFind имеет значение true?

следующая конструкция так же ошибок не даёт
Код:
  ShowMessage(IntToStr(integer(TMyList(2)))); 

вопрос: как проверить что integer есть в списке TMyList?
Ответить с цитированием
  #2  
Старый 12.05.2023, 20:49
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,056
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

В таком виде ничего сделать нельзя, т.к. для подобных типов RTTI не генерируется, а pred и succ работают неправильно (они воспринимают данный тип не как enum, а как integer).

Зато есть workaround с минимальными добавлениями. Фактически, мы создаем рядом с типом константный массив и используем его для подобной проверки вместо самого типа:
Код:
type
  TMyList = (mlOne = 1, mlFive = 5);

const
  TMyListValues : Array [1..2] Of TMyList = (mlOne, mlFive);

function BoolToStr(value : Boolean) : String;
begin
  if Value then Result := 'true' else Result := 'false';
end;

function isDefined(value : Integer) : Boolean;
var
  I : Integer;
begin
  for I := Low(TMyListValues) to High(TMyListValues) do
    begin
      Result := value = Ord(TMyListValues[i]);
      if Result then Break;
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  iTmp1, iTmp2: integer;
begin
  iTmp1 := 2;
  iTmp2 := 1;

  ShowMessage('iTmp1 = ' + BoolToStr(isDefined(iTmp1)) + ', iTmp2 = ' + BoolToStr(isDefined(iTmp2)));
end;

В результате работы получаем следующее сообщение:
Код:
iTmp1 = false, iTmp2 = true
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
zhirnov.ilya.lvovich (13.05.2023)
  #3  
Старый 13.05.2023, 00:49
xchgeaxeax xchgeaxeax вне форума
Прохожий
 
Регистрация: 11.05.2023
Сообщения: 15
Версия Delphi: D7, Laz v2.2.6
Репутация: 10
По умолчанию

А лучше вместо массива использовать set of TMyList = [mlOne, mlFive], если значения не превосходят 255. Хотя диапазон и не большой, но и перечисления со значениями больше чем 255 встречаются редко. Но если значения будут больше этого, тогда массив.
Код:
type TMyList = (mlOne = 1, mlFive = 5);

const mlSet: set of TMyList = [mlOne, mlFive];

var iTmp: Integer;

begin
  for iTmp := 0 to 9 do
    if TMyList(iTmp) in mlSet
      then WriteLn('True')
      else WriteLn('False');
  ReadLn;
end;

Последний раз редактировалось xchgeaxeax, 13.05.2023 в 00:51.
Ответить с цитированием
Этот пользователь сказал Спасибо xchgeaxeax за это полезное сообщение:
zhirnov.ilya.lvovich (13.05.2023)
  #4  
Старый 13.05.2023, 18:15
zhirnov.ilya.lvovich zhirnov.ilya.lvovich вне форума
Прохожий
 
Регистрация: 14.02.2023
Сообщения: 4
Версия Delphi: Delphi 10.4
Репутация: 10
По умолчанию

Ребят, спасибо большое за ответ. Что-то из этого применю.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 04:04.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter