Convert string to enum type using TValue?

I want to convert a string to an enum type using TValue, I googled, but I did not find how to do this.

type 
  TEnumTest = (etFirst, etSecond);

var 
  D: TEnumTest;
begin
  D := StrToENumTest('etFirst');
end;

function StrToEnumTest(pStr:String):TEnumTest;
var 
  V: TValue;
begin
  V := TValue.From<String>(pstr);
  Result := V.AsType<TEnumTest>;
end;

This does not work. It must be something stupid that I do not see - but I did not find it. What did I do wrong?

I know how to use GetEnumValue.

EDIT: @Warren, it goes here, as it is easier to send the code:

  TEnumUtils = class
    class function GetAs<T>(pValor: String): T;
  end;

class function TEnumUtils.GetAs<T>(pValor: String): T;
var
  Tipo: PTypeInfo;
  Temp: Integer;
  PTemp: Pointer;

begin
   Tipo := TypeInfo(T);
   Temp := GetEnumValue(Tipo, pValor);
   PTemp := @Temp;
   Result := T(PTemp^);
end;

Using:

type 
  TEnumTest = (etFirst, etSecond);

var 
  D: TEnumTest;
begin
  D := TEnumUtils.GetAs<TEnumTest>('etFirst');
end;  
+3
source share
4 answers

, , - , TValue. , , . srtings , , , . , TypeInfo.

+2

, ?

Generics RTTI

Enum Generics/RTTI Unit System.RTTI - : TRttiEnumerationType

TRttiEnumerationType (, ), , TypInfo. :

GetName (AValue: T): string; GetValue (AName: string): T; , Generics (thats T). , , .

TRttiEnumerationTypes , , Enums.

TCompass RTTI , .

S: = TRttiEnumerationType.GetName(D); ShowMessage (S); .

D: = TRttiEnumerationType.GetValue(S); ! , .

+5

You can use the same approach as the entry at the top of this page using GetEnumValue. You can easily declare a code like this:

unit Unit3;

interface

uses
   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
   System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, 
   typinfo, Vcl.StdCtrls;

   Type TMyEnumerator=(enm_Case0, enm_Case1, enm_Case2);

   Type TEnumConverter = class
   public
        class function EnumToInt<T>(const enValue: T): Integer;
        class function EnumToString<T>(enValue: T): string;
        class procedure StringToEnum<T>(strValue:String; var enValue:T);
   end;

implementation

class function TEnumConverter.EnumToInt<T>(const enValue: T): Integer;
begin
   Result := 0;
   Move(enValue, Result, sizeOf(enValue));
end;

class function TEnumConverter.EnumToString<T>(enValue: T): string;
begin
  Result := GetEnumName(TypeInfo(T), EnumToInt(enValue));
end;

 class procedure TEnumConverter.StringToEnum<T>(strValue: String; var enValue:T);
   var Tipo : PTypeInfo;
       Temp:Integer;
       PTemp : pointer;
begin
    Tipo := TypeInfo(T);
    Temp := GetEnumValue(Tipo, strValue);
    PTemp := @Temp;
    enValue := T(PTemp^);
end;

procedure TForm3.Button1Click(Sender: TObject);
   var s: String;
       v : TMyEnumerator;
begin
       { ************** Example *************** }

       showmessage(TEnumConverter.EnumToString(enm_Case1)); 

        s := 'enm_Case2';
        TEnumConverter.StringToEnum(s, v);

   case v of
     enm_Case0: showmessage('ok -> enm_Case0');
     enm_Case1: showmessage('ok -> enm_Case1');
     enm_Case2: showmessage('ok -> enm_Case2');
   end;

end;
+1
source

So you know how to do this:

function StrToEnumTest(aStr:String):TEnumTest;
begin
  result := TEnumTest(GetEnumValue(TypeInfo(TEnumTest),aStr));
end;

But you do not want to do this? What for? I wish we did this:

inline function StrToEnumTest(aStr:String):<T>;
begin
  result := <T>(GetEnumValue(TypeInfo(<T>),aStr));
end;
0
source

Source: https://habr.com/ru/post/1737577/


All Articles