Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.03.2019, 18:47   #1
stoi
 
Регистрация: 21.03.2019
Сообщений: 8
По умолчанию Как объявлять константу перечислимого сложного типа?

Часто нужно объявить сложный перечислимый тип.
Например

Код:
type
  TMyType = (mtFirst, mtSecond);
У каждого элемента перечисления должны быть строковые представления и числовые значения (например). Причем обращаться к ним хотелось бы через точку:

Код:
mtFirst.StrName, mtSecond.IntValue
Причем это должна быть константная информация, задаваемая при написании кода, а не во время исполнения программы.

Не могу придумать оптимальный способ - как это красиво и правильно сделать в Delph.
Отдельные константы-записи - они не объединены в перечислимый тип.
Константный массив записей - обращаться только по индексу....
Перепробовал кучу решений - все кажутся неоптимальными.

Что вы думаете?
stoi вне форума Ответить с цитированием
Старый 21.03.2019, 20:04   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

В ABC.NET вроде можно обращаться TMyType.mtFirst.
Все остальное свой язык нужно придумывать.
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 21.03.2019, 20:59   #3
stoi
 
Регистрация: 21.03.2019
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
В ABC.NET вроде можно обращаться TMyType.mtFirst
В Делфи тоже можно Только я ж не о том спрашивал
stoi вне форума Ответить с цитированием
Старый 21.03.2019, 21:03   #4
stoi
 
Регистрация: 21.03.2019
Сообщений: 8
По умолчанию

Допустим нужно объявить тип, описывающий ставки НДС (первое что в голову пришло). Должноа быть 2 фиксированные ставки, у каждой - строковое имя и числовое значение.

Просто интересно - кто как это решает. Понятно, что в Delphi нет простого способа это описать. Один мой коллега настаивает на том, что нужно объявлять коллекцию объектов, а заполнять её в разделе Initialization. Но мне это кажется всё равно "костылем". Во-первых - нелогично не задавать значение констант сразу в коде. Во-вторых - объявлено в одном месте, заполняется - в другом. Затрудняет понимание и читабельность...
stoi вне форума Ответить с цитированием
Старый 21.03.2019, 21:09   #5
stoi
 
Регистрация: 21.03.2019
Сообщений: 8
По умолчанию

Вот в одном из проектов я сделал так:
Код:
  TTax = class
  public
    type
      TValue = (txUndefined,  //< по старой схеме (брать из Tax1Code)
                tx20, tx18, tx10, tx20120, tx18118, tx10110, tx0, txNone);
  protected
    class function GetAsFloat(Index: TTax.TValue): Double; static;
    class function GetName(AValue: TTax.TValue): string; static;
    class function GetAsString(AValue: TTax.TValue): string; static;
  public
    class function FromFloat(AValue: Double): TValue;
  public
    class property Name[Index: TTax.TValue]: string read GetName;
    class property AsString[Index: TTax.TValue]: string read GetAsString;
    class property AsFloat[Index: TTax.TValue]: Double read GetAsFloat;
  end;
Но результат мне не нравится. Всё равно неудобно (

Можно объявить тип record. И насоздавать констант этого типа. Но они будут разрознены. Перебрать к примеру все элементы - не получится, это ведь не коллекция, не массив
stoi вне форума Ответить с цитированием
Старый 21.03.2019, 21:37   #6
stoi
 
Регистрация: 21.03.2019
Сообщений: 8
По умолчанию Как объявлять константу перечислимого сложного типа?

Часто нужно объявить сложный перечислимый тип.
Например

Код:
type
  TMyType = (mtFirst, mtSecond);
У каждого элемента перечисления должны быть строковые представления и числовые значения (например). Причем обращаться к ним хотелось бы через точку:

Код:
mtFirst.StrName, mtSecond.IntValue
Причем это должна быть константная информация, задаваемая при написании кода, а не во время исполнения программы.

Не могу придумать оптимальный способ - как это красиво и правильно сделать в Delph.
Отдельные константы-записи - они не объединены в перечислимый тип.
Константный массив записей - обращаться только по индексу....
Перепробовал кучу решений - все кажутся неоптимальными.

Вот в одном из проектов я сделал так:
Код:
  TTax = class
  public
    type
      TValue = (txUndefined,  //< по старой схеме (брать из Tax1Code)
                tx20, tx18, tx10, tx20120, tx18118, tx10110, tx0, txNone);
  protected
    class function GetAsFloat(Index: TTax.TValue): Double; static;
    class function GetName(AValue: TTax.TValue): string; static;
    class function GetAsString(AValue: TTax.TValue): string; static;
  public
    class function FromFloat(AValue: Double): TValue;
  public
    class property Name[Index: TTax.TValue]: string read GetName;
    class property AsString[Index: TTax.TValue]: string read GetAsString;
    class property AsFloat[Index: TTax.TValue]: Double read GetAsFloat;
  end;
Но результат мне не нравится. Всё равно неудобно (

Можно объявить тип record. И насоздавать констант этого типа. Но они будут разрознены. Перебрать к примеру все элементы - не получится, это ведь не коллекция, не массив
stoi вне форума Ответить с цитированием
Старый 21.03.2019, 22:21   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Цитата:
Перебрать к примеру все элементы - не получится, это ведь не коллекция, не
такой перебор чем не подходит?
Код:
  var xc: TValue;

  for xc:=Low(TValue) to High(TValue) do begin
    ...
  end;
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 22.03.2019, 09:45   #8
stoi
 
Регистрация: 21.03.2019
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
такой перебор чем не подходит?
Код:
  var xc: TValue;

  for xc:=Low(TValue) to High(TValue) do begin
    ...
  end;
Такой подходит. Но я ж говорю - результат мне не нравится
stoi вне форума Ответить с цитированием
Старый 22.03.2019, 11:14   #9
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,515
По умолчанию

Код:
type
 TMyType = (mtFirst =18, mtSecond =20);

procedure TestVal(val: integer);
begin
  case TMyType(val) of
  mtFirst: ShowMessage('first');
  mtSecond: ShowMessage('second');
  else ShowMessage('???');
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  val: integer;
begin
  TestVal(0);

  val:=ord(mtFirst);
  TestVal(val);

  val:=20;
  TestVal(val);

end;
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 22.03.2019, 11:20   #10
stoi
 
Регистрация: 21.03.2019
Сообщений: 8
По умолчанию

Цитата:
Сообщение от evg_m Посмотреть сообщение
Код:
type
 TMyType = (mtFirst =18, mtSecond =20);

procedure TestVal(val: integer);
begin
  case TMyType(val) of
  mtFirst: ShowMessage('first');
  mtSecond: ShowMessage('second');
  else ShowMessage('???');
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  val: integer;
begin
  TestVal(0);

  val:=ord(mtFirst);
  TestVal(val);

  val:=20;
  TestVal(val);

end;
Да это понятно все )). Еще можно 100 вариантов подобных придумать. Но это совсем не то решение, о котором я спрашивал.
И кстати -
Цитата:
(mtFirst =18, mtSecond =20)
- плохая идея. Во первых, так можно закодировать только целые числа 0..255. Во-вторых будут гарантированные проблемы с таким типом, если он будет использоваться где-нить в RTTI
stoi вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

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

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как создать константу составного типа данных? vasypu C# (си шарп) 1 26.01.2019 18:29
Для чего объявлять переменную общего типа а инициализировать частным guroDragon Общие вопросы по Java, Java SE, Kotlin 6 17.02.2016 03:18
Поиск текста с копированием ячеек типа ВПР но для сложного текста! Elkin_087 Microsoft Office Excel 1 24.06.2012 22:06
Использовать перечислимый тип для хранения названий с последующей выдачей значений созданного перечислимого типа (C#) satna Помощь студентам 1 12.09.2011 21:03
Создание перечислимого строкового типа с возможностью использовать как STRING Alex Cones Общие вопросы Delphi 2 21.04.2009 13:56