Цикл нерегулярного перечисления в Delphi - PullRequest
6 голосов
/ 09 ноября 2010

1) Кто-нибудь знает, возможно ли перебрать нерегулярное перечисление в Delphi (XE)?

Цикл нормального перечисления в порядке. От Основы Delphi :

var
  suit : (Hearts, Clubs, Diamonds, Spades);
begin
// Loop 3 times
For suit := Hearts to Diamonds do
   ShowMessage('Suit = '+IntToStr(Ord(suit)));
end;

Но, если вместо этого 'костюм' объявлен как

var
  suit : (Hearts=1, Clubs, Diamonds=10, Spades);

это повторяется 10 раз. Не удивительно, но я хотел бы выполнить цикл 3. Единственное решение, которое я нашел до сих пор, - преобразование перечисления в набор и использование цикла for ... in, как на delphi.about.com .

Итак, если ответ на вопрос 1) отрицательный, то:
2) Как конвертировать из перечисления в Delphi?

Контекст, в котором я его использую, представляет собой массив компонентов блоков редактирования (TEdit) с неправильной нумерацией (edit1, edit5, edit7, edit3, ...). Хотя можно изменить порядок всех полей редактирования, это устраняет причину использования перечисления в качестве гибкого способа, позволяющего добавить поле редактирования в середине перечисления.

Ответы [ 6 ]

7 голосов
/ 09 ноября 2010

У меня сейчас нет компилятора Delphi, но я полагаю, что подход Габра можно значительно улучшить, выполнив

type
  TSuit = (Hearts = 1, Clubs, Diamonds = 10, Spades);

const
  Suits: array[0..3] of TSuit = (Hearts, Clubs, Diamonds, Spades);

Кто знает, может быть, он даже не компилируется.

3 голосов
/ 09 ноября 2010
type
  TSuit = (Hearts=1, Clubs, Diamonds=10, Spades);

var
  suit: TSuit;
  suitEnum: array [1..4] of TSuit;

//initialization
suitEnum[1] := Hearts;
suitEnum[2] := Clubs;
suitEnum[3] := Diamonds;
suitEnum[4] := Spades;

for suit in suitEnum do
  DoSomething(suit);
2 голосов
/ 22 апреля 2011

Я всегда использую

var
  s: TSuit;
begin
  for s := Low(TSuit) to High(TSuit) do
    {something};
end;
0 голосов
/ 15 марта 2016

Следует понимать (и часто это не так), что в тот момент, когда вы помещаете жесткие порядковые присваивания в перечисление, он перестает быть перечисляемым типом Паскаля - он просто становится «мешком констант», которыйне то же самое.Это то, что C-программисты называют перечислениями.Тем не менее, перечислимый тип Паскаля является ORDINAL по всем критериям: он имеет дискретные последовательные значения, которые осмысленно реагируют на базовые операции ORD, PRED, SUCC.Перечисления в C не делают этого, как и перечисления в Pascal, когда вы разделяете ординалы.

Это причина того, что RTTI Delphi в основном отказывается возвращать информацию о типах, как только это было сделано.По сути, тип по сути является tkUnknown и должен рассматриваться как «пакет» констант времени компиляции.Только потому, что он все еще играет на словах ординал и имеет (иногда шаткую) поддержку для использования в наборах, люди верят, что он должен вести себя как правильный перечислимый тип.Лучше просто понять, что это такое на самом деле: намек на перечисляемые значения в C. Избегайте смешивания метафоры кодирования!

Если вы сделаете это, ваше решение станет очевидным: вы используете перечислимый тип (aправильно) индексировать соответствующий массив CONSTANTS.Затем вы можете делать порядковые числа по своему усмотрению, и перечисления сохраняют свои полные определения RTTI как правильное перечисление.Итак: ваш ENUMERATED TYPE содержит правильные неизмененные порядковые значения.Вы получаете свои смешные числа, индексируя массив констант, используя массив перечисления -ergo [MyEnums] byte = (1,3,8,22,99, что угодно)

0 голосов
/ 09 ноября 2010

Грязная опция, полезная для небольших перечислений:

type
  TSuit = (Hearts = 1, Clubs, Diamonds = 10, Spades);
var
  Suit: TSuit;
begin
  for Suit in [Hearts, Clubs, Diamonds] do
    WriteLn(Ord(Suit));

Прекрасно работает в Delphi 2007. Не знаю о старых версиях.Имейте в виду, что использование for Suit in [Hearts..Diamonds] do имеет ту же проблему, что и ваш цикл.Кстати, я использую WriteLn(), потому что я проверял это в консольном приложении.: -)

0 голосов
/ 09 ноября 2010

Цикл с использованием Ord (червы) к Ord (пики)?

...