powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Enum to string и обратно
42 сообщений из 42, показаны все 2 страниц
Enum to string и обратно
    #40040953
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А как бы проще организовать конвертацию энумератора в строку и обратно для таких конечных строк
'lower', 'upper', 'title', 'none', 'assume-lower', 'assume-title', 'assume-upper'?

Функции GetEnumName/GetEnumValue не подходят, т.к. конечные строки содержат знак "-" и я не объявлю такие идентификаторы

Таких энумераторов много, так что не очень хочется под каждый писать отдельные функции конвертации

С уважением, Vasilisk
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40040955
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Напиши свою функцию. Ну или класс, если
требуется что-то большее, чем просто имена.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40040956
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

System.TypInfo.AddEnumElementAliases
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40040957
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> System.TypInfo.AddEnumElementAliases

Ух-ты, круто...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40040971
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
System.TypInfo.AddEnumElementAliases
GetEnumValue заработало. GetEnumName возвращает оригинальное имя
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40040979
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Альтенативный вопрос
Код: pascal
1.
TTestEnum = ([CustomName('b')] a)


Можно ли получить TRttiType для элемента перечисления, чтобы потом у него вызвать GetAttributse()?
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40040988
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Родилaсь такая структура
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
type
  TEnumAliasesManager<T> = record
  strict private
    type
      TEnumValue = record
      case TOrdType of
        otSByte: (SByte: ShortInt);
        otUByte: (UByte: Byte);
        otSWord: (SWord: SmallInt);
        otUWord: (UWord: Word);
        otSLong: (SLong: Integer);
        otULong: (ULong: Cardinal);
      end;
      PEnumValue = ^TEnumValue;
  strict private
    class var
      FAliases: TArray<string>;
  strict private
    class procedure CheckRegistered; static;
    class procedure SizeError; static; inline;
    class function IndexOf(const AStr: string): Integer; static;
  public
    class procedure Register(const AAliases: array of string); static;
    class function EnumToString(const AVal: T): string; static;
    class function StringToEnum(const AVal: string): T; static;
  end;

  EEnumAliasesManagerError = class(Exception);

class procedure TEnumAliasesManager<T>.CheckRegistered;
begin
  if FAliases = nil then
    raise EEnumAliasesManagerError.Create('No aliases registered');
end;

class procedure TEnumAliasesManager<T>.SizeError;
begin
  raise EEnumAliasesManagerError.Create('Unknown enumeration size');
end;

class function TEnumAliasesManager<T>.IndexOf(const AStr: string): Integer;
begin
  for Result := 0 to Length(FAliases) - 1 do begin
    if AStr = FAliases[Result] then
      Exit;
  end;
  raise EEnumAliasesManagerError.CreateFmt('Alias "%s" not found', [AStr]);
end;

class procedure TEnumAliasesManager<T>.Register(
  const AAliases: array of string);
var
  LTypeInfo: PTypeInfo;
  LMinValue: Integer;
  LMaxValue: Integer;
  LLen: Integer;
begin
  LTypeInfo := TypeInfo(T);
  if LTypeInfo^.Kind <> tkEnumeration then
    raise EEnumAliasesManagerError.Create('Type must be Enumeration');
  if LTypeInfo^.Kind <> tkEnumeration then
    raise Exception.Create('Type must be Enumeration');
  LMinValue := LTypeInfo^.TypeData^.MinValue;
  if LMinValue < 0 then begin  // WordBool, LongBool etc
    LMinValue := 0;
    LMaxValue := 1
  end else
    LMaxValue := LTypeInfo^.TypeData^.MaxValue;

  LLen := Length(AAliases);
  if LMaxValue - LMinValue + 1 <> LLen then
    raise Exception.Create('Invalid aliases size');

  SetLength(FAliases, LLen);
  TArray.Copy<string>(AAliases, FAliases, LLen);
end;

class function TEnumAliasesManager<T>.EnumToString(const AVal: T): string;
var
  LTypeInfo: PTypeInfo;
  LEnumVal: PEnumValue;
begin
  CheckRegistered;
  LTypeInfo := TypeInfo(T);
  LEnumVal := @AVal;
  case LTypeInfo^.TypeData^.OrdType of
    otSByte: Result := FAliases[LEnumVal^.SByte];
    otUByte: Result := FAliases[LEnumVal^.UByte];
    otSWord: Result := FAliases[LEnumVal^.SWord];
    otUWord: Result := FAliases[LEnumVal^.UWord];
    otSLong: Result := FAliases[LEnumVal^.SLong];
    otULong: Result := FAliases[LEnumVal^.ULong];
  else
    SizeError;
  end;
end;

class function TEnumAliasesManager<T>.StringToEnum(const AVal: string): T;
var
  LTypeInfo: PTypeInfo;
  LEnumVal: PEnumValue;
  LIdx: Integer;
begin
  CheckRegistered;
  LIdx := IndexOf(AVal);
  LTypeInfo := TypeInfo(T);
  LEnumVal := @Result;
  case LTypeInfo^.TypeData^.OrdType of
    otSByte: LEnumVal^.SByte := LIdx;
    otUByte: LEnumVal^.UByte := LIdx;
    otSWord: LEnumVal^.SWord := LIdx;
    otUWord: LEnumVal^.UWord := LIdx;
    otSLong: LEnumVal^.SLong := LIdx;
    otULong: LEnumVal^.ULong := LIdx;
  else
    SizeError;
  end;
end;

и использование
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
type
  TTestEnum1 = (en11, en12);
  TTestEnum2 = (en21, en22, en23);

procedure TForm1.Button1Click(Sender: TObject);
var
  LStr: string;
  LEn1: TTestEnum1;
  LEn2: TTestEnum2;
begin
  TEnumAliasesManager<TTestEnum1>.Register(['a', 'b']);
  TEnumAliasesManager<TTestEnum2>.Register(['x', 'y', 'z']);
  LStr := TEnumAliasesManager<TTestEnum1>.EnumToString(en12);
  LStr := TEnumAliasesManager<TTestEnum2>.EnumToString(en23);
  LEn1 := TEnumAliasesManager<TTestEnum1>.StringToEnum('b');
  LEn2 := TEnumAliasesManager<TTestEnum2>.StringToEnum('z');
end;

...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041054
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
_Vasilisk_,

System.TypInfo.AddEnumElementAliases


http://docwiki.embarcadero.com/Libraries/Sydney/en/System.TypInfo.AddEnumElementAliases

а справки и примеров нет :(
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041097
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Ммм?
Код: pascal
1.
2.
3.
4.
  if LTypeInfo^.Kind <> tkEnumeration then
    raise EEnumAliasesManagerError.Create('Type must be Enumeration');
  if LTypeInfo^.Kind <> tkEnumeration then
    raise Exception.Create('Type must be Enumeration');
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041099
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

вдруг просочится?
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041315
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp
Ммм?
Рука дрогнула. Дважды Ctrl-V нажал :)
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041371
bk0010
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman
alekcvp,

вдруг просочится?
И такое бывало (в смысле, приходилось писать по 2 одинаковых проверки подрят). На Lotus Notes, ЕМНИП.
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041438
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    LTypeInfo := TypeInfo(T);
  if LTypeInfo^.Kind <> tkEnumeration then
    raise EEnumAliasesManagerError.Create('Type must be Enumeration');

  LMinValue := LTypeInfo^.TypeData^.MinValue;
  if LMinValue < 0 then begin  // WordBool, LongBool etc
    LMinValue := 0;
    LMaxValue := 1
  end else
    LMaxValue := LTypeInfo^.TypeData^.MaxValue;


я бы такие проверки в конструктор класса убрал, это и быстрее и проверка будет при запуске, а не при использовании
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041450
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
kealon(Ruslan)
_Vasilisk_,

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    LTypeInfo := TypeInfo(T);
  if LTypeInfo^.Kind <> tkEnumeration then
    raise EEnumAliasesManagerError.Create('Type must be Enumeration');

  LMinValue := LTypeInfo^.TypeData^.MinValue;
  if LMinValue < 0 then begin  // WordBool, LongBool etc
    LMinValue := 0;
    LMaxValue := 1
  end else
    LMaxValue := LTypeInfo^.TypeData^.MaxValue;



я бы такие проверки в конструктор класса убрал, это и быстрее и проверка будет при запуске, а не при использовании


а я не люблю в конструкторе никаких исключений поднимать
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041458
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А я задачу, аналогичную задаче ТC, сделал через helper, реализовал в нем .ToString для enum и всё работает)
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041680
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
я бы такие проверки в конструктор класса убрал, это и быстрее и проверка будет при запуске, а не при использовании
О! Спасибо за идею!
asutp2
А я задачу, аналогичную задаче ТC, сделал через helper, реализовал в нем .ToString для enum и всё работает)
Замечательно! А если энумераторов десяток? Десять хелперов?
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041704
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
я бы такие проверки в конструктор класса убрал,
Компилятор напутал с очередностью вызова классовых конструкторов. В итоге классовый конструктор, откуда идет вызов метода
Код: pascal
1.
TEnumAliasesManager<T>.Register

вызывается раньше чем классовый конструктор
Код: pascal
1.
TEnumAliasesManager<T>.Create;

Т.е. проверку нужно вставлять в двух местах: и в конструкторе и в методе
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041803
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
kealon(Ruslan)
я бы такие проверки в конструктор класса убрал,
Компилятор напутал с очередностью вызова классовых конструкторов.

есть простое правило: "если программа работает неправильно, значит ты что-то неправильно написал"
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041828
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
есть простое правило: "если программа работает неправильно, значит ты что-то неправильно написал"
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
interface

type
  TClass1<T> = class
  strict private
    class constructor Create;
  public
    class procedure Method; static;
  end;

  TClass2 = class
  strict private
    class constructor Create;
  end;

implementation

class constructor TClass1<T>.Create;
begin
  ShowMessage(ClassName + '.Create');
end;

class procedure TClass1<T>.Method; 
begin
  ShowMessage(ClassName + '.Method');
end;

class constructor TClass2.Create;
begin
  ShowMessage(ClassName + '.Create');
  TClass1<Byte>.Method;
end;

Запускаю и вижу
TClass2.Create
TClass1<Byte>.Method
TClass1<Byte>.CreateНу конечно же я что-то неправильно написал
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041839
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Наверное это потому что ты вызываешь метод класса из конструктора другого класса, нет?..
Никто не обещал что конструктор будет вызываться при любом обращении к классу.

Более того, если прочитать справку то там, внезапно, написано:
Note: Even though the compiler takes care of ordering the initialization of classes, in some complex scenarios, ordering may become random. This happens when the class constructor of a class depends on the state of another class that, in turn, depends on the first class.
У тебя класс2 зависит от класса1, потому что он вызывает его методы, а класс1 зависит от класса2, потому что это дженерик и до первого обращения к нему с указанием типа его вообще не существует.

Более того, дальше тебя ждёт ещё больше сюрпризов, потому что:
Note: The class constructor for a generic class or record may execute multiple times. The exact number of times the class constructor is executed in this case depends on the number of specialized versions of the generic type. For example, the class constructor for a specialized TList<String> class may execute multiple times in the same application.
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041987
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

1-е верно, компилятор может упустить вызов конструктора если он например может его выкинуть
или если "не видит" связи между вызовами - запустить его как получится


авторNote: The class constructor for a generic class or record may execute multiple times. The exact number of times the class constructor is executed in this case depends on the number of specialized versions of the generic type. For example, the class constructor for a specialized TList<String> class may execute multiple times in the same application. а вот это неправда, там такой же счётчик как и у Unit-ов. Эту багу хорошо повыправляли

на 10-ке

Код: plaintext
1.
2.
3.
TClass1<System.Byte>.Create
TClass2.Create
TClass1<System.Byte>.Method
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40041996
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
а вот это неправда, там такой же счётчик как и у Unit-ов. Эту багу хорошо повыправляли

Это цитата из справки, если что. Причём из справки для 10.4.
Так что если ты с чем-то не согласен - пиши сразу в Эмбу 😁
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40042012
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

и что же я им напишу, верните багу назад в соответствии с этой документацией?
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40042013
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Столько проблем, хотя в варианте с хелпером все работает предсказуемо и без багов)))
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40042024
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2,

да я кажется знаю где у _Vasilisk_ бага, он как-то просил пример по одному вопросу "почему так делать нельзя", похоже он сам его и написал
но пока не видно как он его использует, однозначно утверждать нельзя
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40042255
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
на 10-ке
Какой именно 10-ке? У меня 10.3.1
kealon(Ruslan)
но пока не видно как он его использует, однозначно утверждать нельзя
Чего еще не видно? Код я показал
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40042322
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,
10.2 Update 1

ты лишь модуль привёл, а где использование?

вот твой код

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
program Test;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  TClass1<T> = class
  strict private
    class constructor Create;
  public
    class procedure Method; static;
  end;

  TClass2 = class
  strict private
    class constructor Create;
  end;


class constructor TClass1<T>.Create;
begin
  Writeln(ClassName + '.Create');
end;

class procedure TClass1<T>.Method;
begin
  Writeln(ClassName + '.Method');
end;

class constructor TClass2.Create;
begin
  Writeln(ClassName + '.Create');
  TClass1<Byte>.Method;
end;

begin
  TClass2.Create.Destroy;
end.



всё пучком

Код: plaintext
1.
2.
TClass1<System.Byte>.Create
TClass2.Create
TClass1<System.Byte>.Method
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40042611
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
ты лишь модуль привёл, а где использование?
Проверил. Не повторяется. С этим кодом все работает. Странно
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40043175
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
kealon(Ruslan)
ты лишь модуль привёл, а где использование?
Проверил. Не повторяется. С этим кодом все работает. Странно
я тебе и говорю, покажи весь код
полностью модуль где ты это использовал
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40043866
kapas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_,

Гаджимурадов Рустам> System.TypInfo.AddEnumElementAliases

Ух-ты, круто...



Круто-то круто, но скажем в 10.2 разумно использовать невозможно:
Код: pascal
1.
function GetAliasEnumValue(TypeInfo: PTypeInfo; const Name: string): Integer;


не объявлена в интерфейсной секции.

Лучше использовать спец. атрибуты (что-то вроде TEnumAttribute), привязываемые к перечислимому типу:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
  
    TEnumAttribute = class(TCustomAttribute)
    private
        FEnumHint: string;
        FEnumCode: string;
    protected
      function GetEnumCode(): string; virtual;
      procedure SetEnumCode(const AValue: string); virtual;
      function GetEnumHint(): string; virtual;
      procedure SetEnumHint(const AValue: string); virtual;
    protected
        property Code: string read GetEnumCode write SetEnumCode;
        property Hint: string read GetEnumHint write SetEnumHint;
    public
      constructor Create(const ACode: string; const AHint: string = ''); reintroduce; overload; virtual;
      constructor Create(const ACode: byte; const AHint: string = ''); reintroduce; overload; virtual;
      destructor Destroy(); override;
    public
      function Ord<T>(): T; overload;
      function Order<T>(): integer; overload;
    public
        property Code: string read GetEnumCode write SetEnumCode;
        property Hint: string read GetEnumHint write SetEnumHint;
    end;



Можно добавить:


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
    TEnum<T> = record
    public
    strict private
        FValue: T;
    private
      function GetEnumValue(): T;
      procedure SetEnumValue(const AValue: T);
    public
      class function CodeToHint(ACode: string): string; overload; static;
      class function CodeToOrd(ACode: string): integer; overload; static;
      class function CodeToEnum(ACode: string): T; overload; static;
      class function HintToCode(AHint: string): string; overload; static;
      class function HintToOrd(AHint: string): integer; overload; static;
      class function HintToEnum(AHint: string): T; overload; static;
      class function OrdToHint(AOrd: integer): string; overload; static;
      class function OrdToCode(AOrd: integer): string; overload; static;
      class function OrdToEnum(AOrd: integer): T; overload; static;
    public
      class function CodeToHint(ATypeInfo: PTypeInfo; ACode: string): string; overload; static;
      class function CodeToOrd(ATypeInfo: PTypeInfo; ACode: string): integer; overload; static;
      class function HintToCode(ATypeInfo: PTypeInfo; AHint: string): string; overload; static;
      class function HintToOrd(ATypeInfo: PTypeInfo; AHint: string): integer; overload; static;
      class function OrdToHint(ATypeInfo: PTypeInfo; AOrd: integer): string; overload; static;
      class function OrdToCode(ATypeInfo: PTypeInfo; AOrd: integer): string; overload; static;
    public
      class function EnumToHint(AEnum: T): string; overload; static;
      class function EnumToCode(AEnum: T): string; overload; static;
      class function EnumToOrd(AEnum: T): integer; overload; static;
      class function EnumToName(AEnum: T): string; overload; static;
      class function Instance(AOrder: integer): TClass; overload; static;
      class function Instance(AEnum: T): TClass; overload; static;
      class function Instance(ACode: string): TClass; overload; static;
      class procedure Export(ALIST: TText; const AUseCaption: boolean = true); overload; static;
      class procedure Export(ALIST: TStrings; const AUseCaption: boolean = true); overload; static;
      class procedure Export(ALIST: TcxCustomComboBox; const AUseCaption: boolean = true); overload; static;
//      class procedure Export(ALIST: TcxComboBox); overload; static;
//      class procedure Export(ALIST: TcxDBComboBox); overload; static;
    public
      class operator Implicit(const AValue: integer): TEnum<T>;
      class operator Implicit(const AValue: TEnum<T>): integer;
      class operator Implicit(const AValue: T): TEnum<T>;
      class operator Implicit(const AValue: TEnum<T>): T;
      class operator Implicit(const AValue: string): TEnum<T>;
      class operator Implicit(const AValue: TEnum<T>): string;
    public
      class function GetTypeData(): PTypeData; static;
    public
      class function High(): T; static;
      class function Low(): T; static;
      class function Cast<M>(AValue: T): M; inline; static;
      class function IsEnum(): boolean; inline; static;
    public
      function Instance(): TClass; overload;
        property Value: T read GetEnumValue write SetEnumValue;
    end;



Использование всего этого - что-то вроде такого:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
[TEnum('ckCascadeAll','Cascade All')]
[TEnum('ckCascadeMerge','Cascade Merge')]
[TEnum('ckCascadeRefresh','Cascade Refresh')]
[TEnum('ckCascadeRemove','Cascade Remove')]
//------------------------------------------------------------------------------
    TCascadeKind =
      (
          ckCascadeAll
        , ckCascadeMerge
        , ckCascadeRefresh
        , ckCascadeRemove
      );
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40043904
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kapas,

а смысл этой всей городушки, если элементарное SomeDescr[EnumVal] при SomeDescr: array[TEnum] вернет то, что надо
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40043916
kapas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Fr0sT-Brutal
kapas,

а смысл этой всей городушки, если элементарное SomeDescr[EnumVal] при SomeDescr: array[TEnum] вернет то, что надо


Вы везде вставляете константы и явно используете глобальные переменные? И не надоедает?

Ведь если звёзды зажигают- значит- это кому то надо...
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40044083
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kapas
не объявлена в интерфейсной секции.
В 10.3 объявлена. Может плохо ищете?
kapas
Лучше использовать спец. атрибуты
Если бы атрибуты можно было повесить на само значение. А так, в таком виде, сомнительное удовольствие. Лучше было бы уже делать так
Код: pascal
1.
2.
3.
4.
constructor TEnumAttributes.Create(const AHints: array of string);

[TEnum(['Cascade All', 'Cascade Merge','Cascade Refresh' ,'Cascade Remove'])]
TCascadeKind = (


Fr0sT-Brutal
а смысл этой всей городушки, если элементарное SomeDescr[EnumVal] при SomeDescr: array[TEnum] вернет то, что надо
Вернет. И этот вариант был бы идеален. Если бы не требовалось обратное преобразование. А мостить в кучу мест реализацию IndexOf, причем для разных энумераторов, ну такое...
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40044294
kapas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
1.
_Vasilisk_В 10.3 объявлена. Может плохо ищете?
Я же четко указал 10.2. Можете убедиться сами.

Видимо забыли это сделать в 10.2., а в 10.3 исправили.
Хм. На самом деле GetAliasEnumValue вызывается из GetEnumValue косвенно. И это работает. Но похоже - нельзя получить по значению сам алиас.
Ну да ладно. Вещь конечно удобная, но я ее использовать пока не собираюсь.
2.
_Vasilisk_Если бы атрибуты можно было повесить на само значение. А так, в таком виде, сомнительное удовольствие.
Что значить на само значение? Можно привести пример?
Вы имели ввиду следующее?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
TCascadeKind =
      (
[TEnum('Cascade All')]
          ckCascadeAll
        ,
[TEnum('Cascade Merge')]
        ckCascadeMerge
        ,
[TEnum('Cascade Refresh')]
        ckCascadeRefresh
        ,
[TEnum('Cascade Remove')]
        ckCascadeRemove
      );



3.
_Vasilisk_... Лучше было бы уже делать так
Можно сделать и так:
Код: pascal
1.
[TEnum(['Cascade All', 'Cascade Merge','Cascade Refresh' ,'Cascade Remove'])]


, но это не тоже самое что привязать атрибуты к значениям.
Хотя тут есть нюансы, о которых нужно говорить отдельно. Но это - другая история.

4. Такой "штукой", о которой я писал, пользуюсь с момента появления в Delphi атрибутов и с переходом к новым версиям проблем не было. Это часть других тех. решений (сериализация/десериализация; описатели в элементах управления и др.). Для меня решение которое я набросал вполне удобно в использовании. Я не агитирую - просто показываю одно из возможных решений.
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40044310
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kapas
Вы везде вставляете константы и явно используете глобальные переменные? И не надоедает?

Константы вставляю, а при чем тут глобальные переменные, не понял.
_Vasilisk_
Вернет. И этот вариант был бы идеален. Если бы не требовалось обратное преобразование. А мостить в кучу мест реализацию IndexOf, причем для разных энумераторов, ну такое...

А это уже другой вопрос.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
function FindStr(const Item: string; const Values: array of string): Integer;
begin
  for Result := Low(Values) to High(Values) do
    if Item = Values[Result] then
      Exit;
  Result := -1;
end;

// Find string representation in array of strings and return T
// Similar to Val(Str) but Text and Values could be arbitrary.
// Returns T(-1) if Text not found
class function TEnum<T>.Find(const Item: string; const Values: array of string): T;
begin
  Result := Val(FindStr(Item, Values), False);
end;
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40044320
kapas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
P.S.:
Если
авторВы имели ввиду следующее?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
TCascadeKind =
      (
[TEnum('Cascade All')]
          ckCascadeAll
        ,
[TEnum('Cascade Merge')]
        ckCascadeMerge
        ,
[TEnum('Cascade Refresh')]
        ckCascadeRefresh
        ,
[TEnum('Cascade Remove')]
        ckCascadeRemove
      );


Это вы объявить сможете, а использовать, увы - невозможно (см. довольно старое сообщение: https://stackoverflow.com/questions/2134120/delphi-2010-rtti-explore-enumerations).
С того времени ничего не изменилось и вряд ли сейчас разработчики пойдут на то, чтобы реализовать хранение такой RTTI
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40044411
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

а что бы просто не написать парсер?

ckCascadeAll -> "Cascade All"

+ для сложных случаев добавили бы отдельный метод установки
TEnum<T>['Name'] := 'Test';

вполне приемлимо

ещё можно такой фокус сделать

Код: pascal
1.
2.
3.
4.
5.
6.
TSomeEnum = 
(
  seOne,
  seSecond,
  seSomeName = seSecond
)
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40044442
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kapas
Вы имели ввиду следующее?
Ага. Но тогда атрибут уже достать невозможно. Я в первом сообщении этот вопрос поднимал
Fr0sT-Brutal
А это уже другой вопрос.
Этот вопрос был поднят в самом первом сообщении. А еще там же было написано, что энумераторов много. И на каждый чих передавать массив констант, с вероятностью однажды передать другой массив - это на любителя
kealon(Ruslan)
а что бы просто не написать парсер?
Потому что мой первый вариант с дженериком отлично работает. Причем значительно лучше чем предлагаемые здесь "улучшения и упрощения"
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40044508
kapas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По-поводу инициализации: будете прописывать ее в секции инициализации? Что вы например, будете делать при использовании этого вашего реестра в приложении требующего сериализацию/десериализацию?
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40044532
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и
_Vasilisk_
kealon(Ruslan)
а что бы просто не написать парсер?
Потому что мой первый вариант с дженериком отлично работает. Причем значительно лучше чем предлагаемые здесь "улучшения и упрощения"
пока у тебя довольно посредственно

  • TEnumAliasesManager<T>.IndexOf - перебор
  • нет проверки использования пока не вызовется хоть одна функция
  • TEnumAliasesManager<T>.Register сложно проверяется
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40044557
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kapas
Что вы например, будете делать при использовании этого вашего реестра в приложении требующего сериализацию/десериализацию?
Не понял вопроса вообще. Ну пусть требует. Я не против
kealon(Ruslan)
пока у тебя довольно посредственно
Пока это лучшее, что тут было
kealon(Ruslan)
TEnumAliasesManager<T>.IndexOf - перебор
Вопрос производительности не стоит вот прямо вообще
kealon(Ruslan)
нет проверки использования пока не вызовется хоть одна функция
Какой проверки использования?
kealon(Ruslan)
[li]TEnumAliasesManager<T>.Register сложно проверяется
Даже не знаю что ответить. А где сложность?
...
Рейтинг: 0 / 0
Enum to string и обратно
    #40044629
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
kealon(Ruslan)
пока у тебя довольно посредственно
Пока это лучшее, что тут было
так се утверждение
ИМХО:
  • 22278584 - Лучше, чем ваш вариант, так как декларативный и всё расположено в одном месте, хотя и не решает проблему 3 "проверка и поддержка", но не исключает принципиально и возможность переинициализации потом, как в вашем варианте
  • "Вопрос производительности не стоит вот прямо вообще" - ну ладно, "не стоит и не стоит" хотя мелочь и вообще ничего не стоит сделать
  • Скомплексовав предыдущее с 22274473 сразу решится проблема проверки на этапе запуска. Хотя бы для дебуга это делать стоит, минимальная защита от дурака очень нужна при сопровождении
  • 22279462 - вообще можно избавиться от вторичных описаний в большинстве случаев
...
Рейтинг: 0 / 0
42 сообщений из 42, показаны все 2 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Enum to string и обратно
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]