我想使用TValue将字符串转换为枚举类型,我用谷歌搜索但我没有找到如何做到这一点。
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;
它不起作用。那一定是我看不到的傻事 - 但我没有 找到了。我做错了什么?
我知道如何使用GetEnumValue。
编辑:@Warren,因为这更容易发布代码: 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;
用法:
type
TEnumTest = (etFirst, etSecond);
var
D: TEnumTest;
begin
D := TEnumUtils.GetAs<TEnumTest>('etFirst');
end;
答案 0 :(得分:5)
这就是你要找的东西吗?
Using Generics & RTTI to get enum string name or enum value
使用Generics / RTTI Unit System.RTTI进行枚举转换 平台,包含一个很好的类,用于将枚举转换为字符串和 back:TRttiEnumerationType
TRttiEnumerationType类有两个类函数(方法你 可以调用而无需创建类的实例)来清理 使用TypInfo方法所需的代码。易读 这些方法声明的版本是:
类函数GetName(AValue:T):string;阶级功能 GetValue(AName:string):T;注意这些方法使用泛型(即 T位)。泛型非常酷,因为它们允许你写 功能一次,然后在不同的类型重用它 代码中的时间。
在这种情况下,TRttiEnumerationType的泛型方法可供使用 仅使用Enums而不是其他类类型作为定义的功能 是针对Enum的。
在将RTTI添加到用途后,立即转换TCompass枚举 看起来像这样。
S:= TRttiEnumerationType.GetName(D); ShowMessage(S);至 从字符串转换回来也更简单。
D:= TRttiEnumerationType.GetValue(S);多么容易 那要读!因为我们只需要声明一次类型,我们 在代码中愚蠢地复制粘贴错误的可能性较小。
答案 1 :(得分:3)
您可以使用与使用GetEnumValue在本页顶部编写相同的方法。您可以轻松声明如下代码块:
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;
答案 2 :(得分:2)
你没有看到的是TValue的设计方式。它专门用作包含值的方法,而不是转换它们的方法。如果你想在srtings和enums之间进行转换,就像你说的那样,你已经知道了。在TypeInfo中使用为此目的提供的功能。
答案 3 :(得分:1)
所以你知道如何做到这一点:
function StrToEnumTest(aStr:String):TEnumTest;
begin
result := TEnumTest(GetEnumValue(TypeInfo(TEnumTest),aStr));
end;
但你不想这样做吗?为什么?我希望我们能做到这一点:
inline function StrToEnumTest(aStr:String):<T>;
begin
result := <T>(GetEnumValue(TypeInfo(<T>),aStr));
end;