TValue.AsType‹T› с типами перечисления в Delphi

Пишем это в Delphi

uses System.Classes;
...
var
  A: TAlignment;
  Value: TValue;
begin
  Value := 0;
  A := Value.AsType<TAlignment>();
end;

поднимает EInvalidCast в AsType.

Есть ли способ привести к любому типу перечисления из целочисленного значения с помощью TValue?

Это, конечно, очевидный ответ:

A := TAlignment(Value);

но я хочу предоставить общую функцию, которая работает и с другими типами.


person Jouni Aro    schedule 28.12.2018    source источник
comment
Загляните в TValue.FromOrdinal. Ваш пример пытается использовать TValue для преобразования типов, это не совсем то, для чего предназначен TValue.   -  person nil    schedule 28.12.2018
comment
Что ж, в моем случае фактически задана часть «Значение: = 0», и фактическая проблема заключается в преобразовании. Я могу оставить это для жесткого приведения, что не так очевидно, поэтому вместо этого я хотел бы включить использование AsType или чего-то подобного. Это то, что привело меня к этому изначально: вариант как varinteger вместо varuint32"> stackoverflow.com/questions/52946989/   -  person Jouni Aro    schedule 28.12.2018
comment
Я думаю, что это приведение было бы незаконным как присваивание, отсюда и ошибка. Лично я использую свой вспомогательный тип для таких преобразований. Это кажется слишком тяжелым для использования TValue.   -  person David Heffernan    schedule 28.12.2018
comment
@DavidHeffernan Да, я тоже так думал. Но я бы все же хотел как-то его включить, если это возможно.   -  person Jouni Aro    schedule 28.12.2018
comment
Вы будете получать исключение каждый раз. Я бы избегал TValue и использовал универсальный вспомогательный тип, чтобы делать то, что вам нужно. В Spring4D есть пример.   -  person David Heffernan    schedule 28.12.2018
comment
Тх, надо будет посмотреть. Но я думаю, что мне удалось решить эту проблему. Напишу ответ.   -  person Jouni Aro    schedule 28.12.2018
comment
Spring.ValueConverters.pas, похоже, также использует TValue для преобразований. Итак, какой из них вы имели в виду?   -  person Jouni Aro    schedule 28.12.2018
comment
Я имею в виду такой код: stackoverflow.com/a/21399696/505088   -  person David Heffernan    schedule 28.12.2018
comment
Тх. Это конкретное решение Enum, и оно хорошо подходит для этого. Но это не ответ на мой вопрос :)   -  person Jouni Aro    schedule 28.12.2018
comment
Нет. Это не так. Но это правильный способ решить вашу настоящую проблему, если действительно ваша проблема заключается в преобразовании из порядкового в перечисляемый тип.   -  person David Heffernan    schedule 29.12.2018
comment
Моя проблема заключалась в том, как получить перечисление из TValue, когда оно было добавлено туда как целое число.   -  person Jouni Aro    schedule 29.12.2018


Ответы (1)


Это, кажется, делает это:

  if (PTypeInfo(TypeInfo(TAlignment))^.Kind = tkEnumeration) and (Value.TypeInfo.Kind = tkInteger ) then
    case System.TypInfo.GetTypeData(TypeInfo(TAlignment))^.OrdType of
      otUByte, otSByte: PByte(@A)^ := Value.AsInteger;
      otUWord, otSWord: PWord(@A)^ := Value.AsInteger;
      otULong, otSLong: PInteger(@A)^ := Value.AsInteger;
    end
  else
    A := Value.AsType<TAlignment>();

где TAalignment также может быть T в универсальной функции.

(Скопировал идею из TRttiEnumerationType.GetValue)

person Jouni Aro    schedule 28.12.2018
comment
Зачем вам использовать TValue? - person David Heffernan; 28.12.2018
comment
stackoverflow .com/questions/52946989/ - person Jouni Aro; 28.12.2018