2

Writing this in Delphi

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

raises EInvalidCast at AsType.

Is there a way to cast to any enumeration type from an integer value with TValue?

This is of course the obvious answer:

A := TAlignment(Value);

but I wish to provide a generic function that works with other types as well.

Jouni Aro
  • 2,099
  • 14
  • 30
  • 2
    Have a look into `TValue.FromOrdinal`. Your example is trying to use `TValue` to convert types, that's not really what `TValue` is meant to be used for. – nil Dec 28 '18 at 14:09
  • Well, in my case the 'Value := 0' part is actually given - and the actual issue is the conversion. I can leave it for the hard cast, which is just not that obvious, so I would like to enable the usage of AsType or something similar instead. This is what brought me to this originally: https://stackoverflow.com/questions/52946989/delphi-enums-to-variant-as-varinteger-instead-of-varuint32 – Jouni Aro Dec 28 '18 at 14:21
  • I think that cast would be illegal as an assignment, hence the error. Personally I use my helper type for such conversions. It seems way too heavy to use TValue. – David Heffernan Dec 28 '18 at 14:21
  • @DavidHeffernan Yes, that's what I thought as well. But I would still like to enable it somehow, if possible. – Jouni Aro Dec 28 '18 at 14:22
  • You'll get the the exception every time. I'd avoid TValue and use a generic helper type to do what you need. There's an example in Spring4D. – David Heffernan Dec 28 '18 at 14:31
  • Tx, will have to look. But I think I managed to solve this. Will write an answer. – Jouni Aro Dec 28 '18 at 14:36
  • Spring.ValueConverters.pas seems to use TValue for the conversions as well. So, which one did you mean? – Jouni Aro Dec 28 '18 at 14:54
  • I have in mind code like this https://stackoverflow.com/a/21399696/505088 – David Heffernan Dec 28 '18 at 16:02
  • Tx. That is an Enum specific solution and good for that. However, it does not answer to my question :) – Jouni Aro Dec 28 '18 at 16:56
  • No. It doesn't. But it's the right way to solve your actual problem, if indeed your problem is converting from ordinal to enumerated type. – David Heffernan Dec 28 '18 at 23:38
  • My problem was how to get an enum out of TValue, when it has been added there as an Integer. – Jouni Aro Dec 29 '18 at 19:55

1 Answers1

-1

This seems to do it:

  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>();

where TAlignment can also be T in a generic function.

(Copied the idea from TRttiEnumerationType.GetValue)

Jouni Aro
  • 2,099
  • 14
  • 30