Delphi 用于将枚举转换为字符串并返回的泛型函数
我正在尝试编写将枚举转换为字符串并再次转换的函数 即:Delphi 用于将枚举转换为字符串并返回的泛型函数,delphi,generics,pascal,Delphi,Generics,Pascal,我正在尝试编写将枚举转换为字符串并再次转换的函数 即: t转换=类 严格保密 公众的 类函数StringToEnumeration(x:String):T; 类函数EnumerationToString(x:T):String; 结束; 在实现部分,我有 uses System.TypInfo ; class function TConversions.StringToEnumeration<T>(x:String):T; begin Result := T(GetEn
t转换=类
严格保密
公众的
类函数StringToEnumeration(x:String):T;
类函数EnumerationToString(x:T):String;
结束;
在实现部分,我有
uses
System.TypInfo
;
class function TConversions.StringToEnumeration<T>(x:String):T;
begin
Result := T(GetEnumValue(TypeInfo(T), x));
end;
class function TConversions.EnumerationToString<T>(x:T):String;
begin
Result := GetEnumName(TypeInfo(T), integer(x));
end;
使用
System.TypInfo
;
类函数TConversions.StringToEnumeration(x:String):T;
开始
结果:=T(GetEnumValue(TypeInfo(T),x));
结束;
类函数TConversions.EnumerationToString(x:T):字符串;
开始
结果:=GetEnumName(TypeInfo(T),integer(x));
结束;
问题是,在pascal中,枚举的类型不是T:class
。我也不能使用t:record
在pascal中可以这样做吗?似乎没有
T:enum
泛型类型约束,因此我认为您最好在运行时检查类型,如下所示:
Edit:根据David的评论,我添加了T:record
约束,该约束可用于约束值类型(并排除类类型)
类型
t转换=类
公众的
类函数StringToEnumeration(常量S:string):T;
类函数EnumerationToString(值:T):字符串;
结束;
类函数TConversions.EnumerationToString(值:T):字符串;
变量
P:PTypeInfo;
开始
P:=PTypeInfo(TypeInfo(T));
案例P^。有点
tk消耗:
案例GetTypeData(P)^.OrdType of
otSByte,otUByte:
结果:=GetEnumName(P,PByte(@Value)^);
奥特沃德,奥特沃德:
结果:=GetEnumName(P,PWord(@Value)^);
奥特斯隆,奥特隆:
结果:=GetEnumName(P,PCardinal(@Value)^);
结束;
其他的
raise EArgumentException.CreateFmt('类型%s不是枚举',[P^.Name]);
结束;
结束;
类函数TConversions.StringToEnumeration(常量S:string):T;
变量
P:PTypeInfo;
开始
P:=PTypeInfo(TypeInfo(T));
案例P^。有点
tk消耗:
案例GetTypeData(P)^.OrdType of
otSByte,otUByte:
PByte(@Result)^:=GetEnumValue(P,S);
奥特沃德,奥特沃德:
PWord(@Result)^:=GetEnumValue(P,S);
奥特斯隆,奥特隆:
PCardinal(@Result)^:=GetEnumValue(P,S);
结束;
其他的
raise EArgumentException.CreateFmt('类型%s不是枚举',[P^.Name]);
结束;
结束;
你需要稍微摆弄一下东西。枚举没有泛型,因此我们通过使用字节、单词和基数在枚举之间进行强制转换来绕过它
program Project6;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, System.TypInfo;
type
TConversions<T> = record
class function StringToEnumeration(x: String): T; static;
class function EnumerationToString(x: T): String; static;
end;
class function TConversions<T>.StringToEnumeration(x: String): T;
begin
case Sizeof(T) of
1: PByte(@Result)^ := GetEnumValue(TypeInfo(T), x);
2: PWord(@Result)^ := GetEnumValue(TypeInfo(T), x);
4: PCardinal(@Result)^ := GetEnumValue(TypeInfo(T), x);
end;
end;
class function TConversions<T>.EnumerationToString(x: T): String;
begin
case Sizeof(T) of
1: Result := GetEnumName(TypeInfo(T), PByte(@x)^);
2: Result := GetEnumName(TypeInfo(T), PWord(@x)^);
4: Result := GetEnumName(TypeInfo(T), PCardinal(@x)^);
end;
end;
type
TMyEnum = (me_One, me_Two, me_Three);
TMyEnum2 = (m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15,m16,m17,m18,m19,m20,
m21,m22,m23,m24,m25,m26,m27,m28,m29,m30,m31,m32,m33,m34,m35,m36,m37,m38,m39,m40,
m41,m42,m43,m44,m45,m46,m47,m48,m49,m50,m51,m52,m53,m54,m55,m56,m57,m58,m59,m60,
ma1,ma2,ma3,ma4,ma5,ma6,ma7,ma8,ma9,ma10,ma11,ma12,ma13,ma14,ma15,ma16,ma17,ma18,ma19,ma20,
ma21,ma22,ma23,ma24,ma25,ma26,ma27,ma28,ma29,ma30,ma31,ma32,ma33,ma34,ma35,ma36,ma37,ma38,ma39,
ma40,ma41,ma42,ma43,ma44,ma45,ma46,ma47,ma48,ma49,ma50,ma51,ma52,ma53,ma54,ma55,ma56,ma57,ma58,ma59,ma60,
mb1,mb2,mb3,mb4,mb5,mb6,mb7,mb8,mb9,mb10,mb11,mb12,mb13,mb14,mb15,mb16,mb17,mb18,mb19,
mb20,mb21,mb22,mb23,mb24,mb25,mb26,mb27,mb28,mb29,mb30,mb31,mb32,mb33,mb34,mb35,mb36,mb37,mb38,mb39,
mb40,mb41,mb42,mb43,mb44,mb45,mb46,mb47,mb48,mb49,mb50,mb51,mb52,mb53,mb54,mb55,mb56,mb57,mb58,mb59,mb60,
mc1,mc2,mc3,mc4,mc5,mc6,mc7,mc8,mc9,mc10,mc11,mc12,mc13,mc14,mc15,mc16,mc17,mc18,mc19,
mc20,mc21,mc22,mc23,mc24,mc25,mc26,mc27,mc28,mc29,mc30,mc31,mc32,mc33,mc34,mc35,mc36,mc37,mc38,mc39,
mc40,mc41,mc42,mc43,mc44,mc45,mc46,mc47,mc48,mc49,mc50,mc51,mc52,mc53,mc54,mc55,mc56,mc57,mc58,mc59,mc60,
md1,md2,md3,md4,md5,md6,md7,md8,md9,md10,md11,md12,md13,md14,md15,md16,md17,md18,md19,
md20,md21,md22,md23,md24,md25,md26,md27,md28,md29,md30,md31,md32,md33,md34,md35,md36,md37,md38,md39,
md40,md41,md42,md43,md44,md45,md46,md47,md48,md49,md50,md51,md52,md53,md54,md55,md56,md57,md58,md59,md60,
me1,me2,me3,me4,me5,me6,me7,me8,me9,me10,me11,me12,me13,me14,me15,me16,me17,me18,me19,
me20,me21,me22,me23,me24,me25,me26,me27,me28,me29,me30,me31,me32,me33,me34,me35,me36,me37,me38,me39,
me40,me41,me42,me43,me44,me45,me46,me47,me48,me49,me50,me51,me52,me53,me54,me55,me56,me57,me58,me59,me60,
mf1,mf2,mf3,mf4,mf5,mf6,mf7,mf8,mf9,mf10,mf11,mf12,mf13,mf14,mf15,mf16,mf17,mf18,mf19,
mf20,mf21,mf22,mf23,mf24,mf25,mf26,mf27,mf28,mf29,mf30,mf31,mf32,mf33,mf34,mf35,mf36,mf37,mf38,mf39,
mf40,mf41,mf42,mf43,mf44,mf45,mf46,mf47,mf48,mf49,mf50,mf51,mf52,mf53,mf54,mf55,mf56,mf57,mf58,mf59,mf60);
var
enum: TMyEnum;
enum2: TMyEnum2;
begin
enum := me_Two;
WriteLn(TConversions<TMyEnum>.EnumerationToString(enum));
enum := me_One;
WriteLn(TConversions<TMyEnum>.EnumerationToString(enum));
enum := TConversions<TMyEnum>.StringToEnumeration('me_Three');
WriteLn(TConversions<TMyEnum>.EnumerationToString(enum));
enum2 := m17;
WriteLn(TConversions<TMyEnum2>.EnumerationToString(enum2));
ReadLn;
end.
程序项目6;
{$APPTYPE控制台}
{$R*.res}
使用
System.SysUtils,System.TypInfo;
类型
t转换=记录
类函数StringToEnumeration(x:String):T;静止的
类函数EnumerationToString(x:T):String;静止的
结束;
类函数TConversions.StringToEnumeration(x:String):T;
开始
第(T)类案件
1:PByte(@Result)^:=GetEnumValue(TypeInfo(T),x);
2:PWord(@Result)^:=GetEnumValue(TypeInfo(T),x);
4:PCardinal(@Result)^:=GetEnumValue(TypeInfo(T),x);
结束;
结束;
类函数TConversions.EnumerationToString(x:T):字符串;
开始
第(T)类案件
1:结果:=GetEnumName(TypeInfo(T),PByte(@x)^);
2:结果:=GetEnumName(TypeInfo(T),PWord(@x)^);
4:结果:=GetEnumName(TypeInfo(T),PCardinal(@x)^);
结束;
结束;
类型
TMyEnum=(我一,我二,我三);
TMyEnum2=(m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15,m16,m17,m18,m19,m20,
m21、m22、m23、m24、m25、m26、m27、m28、m29、m30、m31、m32、m33、m34、m35、m36、m37、m38、m39、m40、,
m41,m42,m43,m44,m45,m46,m47,m48,m49,m50,m51,m52,m53,m54,m55,m56,m57,m58,m59,m60,
ma1、ma2、ma3、ma4、ma5、ma6、ma7、ma8、ma9、ma10、ma11、ma12、ma13、ma14、ma15、ma16、ma17、ma18、ma19、ma20、,
ma21、ma22、ma23、ma24、ma25、ma26、ma27、ma28、ma29、ma30、ma31、ma32、ma33、ma34、ma35、ma36、ma37、ma38、ma39、,
ma40、ma41、ma42、ma43、ma44、ma45、ma46、ma47、ma48、ma49、ma50、ma51、ma52、ma53、ma54、ma55、ma56、ma57、ma58、ma59、ma60、,
mb1、mb2、mb3、mb4、mb5、mb6、mb7、mb8、mb9、mb10、mb11、mb12、mb13、mb14、mb15、mb16、mb17、mb18、mb19、,
mb20、mb21、mb22、mb23、mb24、mb25、mb26、mb27、mb28、mb29、mb30、mb31、mb32、mb33、mb34、mb35、mb36、mb37、mb38、mb39、,
mb40、mb41、mb42、mb43、mb44、mb45、mb46、mb47、mb48、mb49、mb50、mb51、mb52、mb53、mb54、mb55、mb56、mb57、mb58、mb59、mb60、,
mc1、mc2、mc3、mc4、mc5、mc6、mc7、mc8、mc9、mc10、mc11、mc12、mc13、mc14、mc15、mc16、mc17、mc18、mc19、,
mc20、mc21、mc22、mc23、mc24、mc25、mc26、mc27、mc28、mc29、mc30、mc31、mc32、mc33、mc34、mc35、mc36、mc37、mc38、mc39、,
mc40、mc41、mc42、mc43、mc44、mc45、mc46、mc47、mc48、mc49、mc50、mc51、mc52、mc53、mc54、mc55、mc56、mc57、mc58、mc59、mc60、,
md1、md2、md3、md4、md5、md6、md7、md8、md9、md10、md11、md12、md13、md14、md15、md16、md17、md18、md19、,
md20、md21、md22、md23、md24、md25、md26、md27、md28、md29、md30、md31、md32、md33、md34、md35、md36、md37、md38、md39、,
md40、md41、md42、md43、md44、md45、md46、md47、md48、md49、md50、md51、md52、md53、md54、md55、md56、md57、md58、md59、md60、,
me1、me2、me3、me4、me5、me6、me7、me8、me9、me10、me11、me12、me13、me14、me15、me16、me17、me18、me19、,
me20、me21、me22、me23、me24、me25、me26、me27、me28、me29、me30、me31、me32、me33、me34、me35、me36、me37、me38、me39、,
me40、me41、me42、me43、me44、me45、me46、me47、me48、me49、me50、me51、me52、me53、me54、me55、me56、me57、me58、me59、me60、,
mf1、mf2、mf3、mf4、mf5、mf6、mf7、mf8、mf9、mf10、mf11、mf12、mf13、mf14、mf15、mf16、mf17、mf18、mf19、,
mf20、mf21、mf22、mf23、mf24、mf25、mf26、mf27、mf28、mf29、mf30、mf31、mf32、mf33、mf34、mf35、mf36、mf37、mf38、mf39、,
mf40、mf41、mf42、mf43、mf44、mf45、mf46、mf47、mf48、mf49、mf50、mf51、mf52、mf53、mf54、mf55、mf56、mf57、mf58、mf59、mf60);
变量
枚举:TMyEnum;
枚举2:TMyEnum2;
开始
枚举:=me_二;
WriteLn(TConversions.EnumerationToString(enum));
枚举:=me_One;
WriteLn(TConversions.EnumerationToString(enum));
enum:=t转换.StringToEnumeration('me_Three');
WriteLn(t转换)。
type
TConversions = class
public
class function StringToEnumeration<T: record>(const S: string): T;
class function EnumerationToString<T: record>(Value: T): string;
end;
class function TConversions.EnumerationToString<T>(Value: T): string;
var
P: PTypeInfo;
begin
P := PTypeInfo(TypeInfo(T));
case P^.Kind of
tkEnumeration:
case GetTypeData(P)^.OrdType of
otSByte, otUByte:
Result := GetEnumName(P, PByte(@Value)^);
otSWord, otUWord:
Result := GetEnumName(P, PWord(@Value)^);
otSLong, otULong:
Result := GetEnumName(P, PCardinal(@Value)^);
end;
else
raise EArgumentException.CreateFmt('Type %s is not enumeration', [P^.Name]);
end;
end;
class function TConversions.StringToEnumeration<T>(const S: string): T;
var
P: PTypeInfo;
begin
P := PTypeInfo(TypeInfo(T));
case P^.Kind of
tkEnumeration:
case GetTypeData(P)^.OrdType of
otSByte, otUByte:
PByte(@Result)^ := GetEnumValue(P, S);
otSWord, otUWord:
PWord(@Result)^ := GetEnumValue(P, S);
otSLong, otULong:
PCardinal(@Result)^ := GetEnumValue(P, S);
end;
else
raise EArgumentException.CreateFmt('Type %s is not enumeration', [P^.Name]);
end;
end;
program Project6;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, System.TypInfo;
type
TConversions<T> = record
class function StringToEnumeration(x: String): T; static;
class function EnumerationToString(x: T): String; static;
end;
class function TConversions<T>.StringToEnumeration(x: String): T;
begin
case Sizeof(T) of
1: PByte(@Result)^ := GetEnumValue(TypeInfo(T), x);
2: PWord(@Result)^ := GetEnumValue(TypeInfo(T), x);
4: PCardinal(@Result)^ := GetEnumValue(TypeInfo(T), x);
end;
end;
class function TConversions<T>.EnumerationToString(x: T): String;
begin
case Sizeof(T) of
1: Result := GetEnumName(TypeInfo(T), PByte(@x)^);
2: Result := GetEnumName(TypeInfo(T), PWord(@x)^);
4: Result := GetEnumName(TypeInfo(T), PCardinal(@x)^);
end;
end;
type
TMyEnum = (me_One, me_Two, me_Three);
TMyEnum2 = (m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15,m16,m17,m18,m19,m20,
m21,m22,m23,m24,m25,m26,m27,m28,m29,m30,m31,m32,m33,m34,m35,m36,m37,m38,m39,m40,
m41,m42,m43,m44,m45,m46,m47,m48,m49,m50,m51,m52,m53,m54,m55,m56,m57,m58,m59,m60,
ma1,ma2,ma3,ma4,ma5,ma6,ma7,ma8,ma9,ma10,ma11,ma12,ma13,ma14,ma15,ma16,ma17,ma18,ma19,ma20,
ma21,ma22,ma23,ma24,ma25,ma26,ma27,ma28,ma29,ma30,ma31,ma32,ma33,ma34,ma35,ma36,ma37,ma38,ma39,
ma40,ma41,ma42,ma43,ma44,ma45,ma46,ma47,ma48,ma49,ma50,ma51,ma52,ma53,ma54,ma55,ma56,ma57,ma58,ma59,ma60,
mb1,mb2,mb3,mb4,mb5,mb6,mb7,mb8,mb9,mb10,mb11,mb12,mb13,mb14,mb15,mb16,mb17,mb18,mb19,
mb20,mb21,mb22,mb23,mb24,mb25,mb26,mb27,mb28,mb29,mb30,mb31,mb32,mb33,mb34,mb35,mb36,mb37,mb38,mb39,
mb40,mb41,mb42,mb43,mb44,mb45,mb46,mb47,mb48,mb49,mb50,mb51,mb52,mb53,mb54,mb55,mb56,mb57,mb58,mb59,mb60,
mc1,mc2,mc3,mc4,mc5,mc6,mc7,mc8,mc9,mc10,mc11,mc12,mc13,mc14,mc15,mc16,mc17,mc18,mc19,
mc20,mc21,mc22,mc23,mc24,mc25,mc26,mc27,mc28,mc29,mc30,mc31,mc32,mc33,mc34,mc35,mc36,mc37,mc38,mc39,
mc40,mc41,mc42,mc43,mc44,mc45,mc46,mc47,mc48,mc49,mc50,mc51,mc52,mc53,mc54,mc55,mc56,mc57,mc58,mc59,mc60,
md1,md2,md3,md4,md5,md6,md7,md8,md9,md10,md11,md12,md13,md14,md15,md16,md17,md18,md19,
md20,md21,md22,md23,md24,md25,md26,md27,md28,md29,md30,md31,md32,md33,md34,md35,md36,md37,md38,md39,
md40,md41,md42,md43,md44,md45,md46,md47,md48,md49,md50,md51,md52,md53,md54,md55,md56,md57,md58,md59,md60,
me1,me2,me3,me4,me5,me6,me7,me8,me9,me10,me11,me12,me13,me14,me15,me16,me17,me18,me19,
me20,me21,me22,me23,me24,me25,me26,me27,me28,me29,me30,me31,me32,me33,me34,me35,me36,me37,me38,me39,
me40,me41,me42,me43,me44,me45,me46,me47,me48,me49,me50,me51,me52,me53,me54,me55,me56,me57,me58,me59,me60,
mf1,mf2,mf3,mf4,mf5,mf6,mf7,mf8,mf9,mf10,mf11,mf12,mf13,mf14,mf15,mf16,mf17,mf18,mf19,
mf20,mf21,mf22,mf23,mf24,mf25,mf26,mf27,mf28,mf29,mf30,mf31,mf32,mf33,mf34,mf35,mf36,mf37,mf38,mf39,
mf40,mf41,mf42,mf43,mf44,mf45,mf46,mf47,mf48,mf49,mf50,mf51,mf52,mf53,mf54,mf55,mf56,mf57,mf58,mf59,mf60);
var
enum: TMyEnum;
enum2: TMyEnum2;
begin
enum := me_Two;
WriteLn(TConversions<TMyEnum>.EnumerationToString(enum));
enum := me_One;
WriteLn(TConversions<TMyEnum>.EnumerationToString(enum));
enum := TConversions<TMyEnum>.StringToEnumeration('me_Three');
WriteLn(TConversions<TMyEnum>.EnumerationToString(enum));
enum2 := m17;
WriteLn(TConversions<TMyEnum2>.EnumerationToString(enum2));
ReadLn;
end.
type
TEnumeration<T: record> = class
strict private
class function TypeInfo: PTypeInfo; inline; static;
class function TypeData: PTypeData; inline; static;
public
class function IsEnumeration: Boolean; static;
class function ToOrdinal(Enum: T): Integer; inline; static;
class function FromOrdinal(Value: Integer): T; inline; static;
class function ToString(Enum: T): string; inline; static;
class function FromString(const S: string): T; inline; static;
class function MinValue: Integer; inline; static;
class function MaxValue: Integer; inline; static;
class function InRange(Value: Integer): Boolean; inline; static;
class function EnsureRange(Value: Integer): Integer; inline; static;
end;
{ TEnumeration<T> }
class function TEnumeration<T>.TypeInfo: PTypeInfo;
begin
Result := System.TypeInfo(T);
end;
class function TEnumeration<T>.TypeData: PTypeData;
begin
Result := TypInfo.GetTypeData(TypeInfo);
end;
class function TEnumeration<T>.IsEnumeration: Boolean;
begin
Result := TypeInfo.Kind=tkEnumeration;
end;
class function TEnumeration<T>.ToOrdinal(Enum: T): Integer;
begin
Assert(IsEnumeration);
Assert(SizeOf(Enum)<=SizeOf(Result));
Result := 0; // needed when SizeOf(Enum) < SizeOf(Result)
Move(Enum, Result, SizeOf(Enum));
Assert(InRange(Result));
end;
class function TEnumeration<T>.FromOrdinal(Value: Integer): T;
begin
Assert(IsEnumeration);
Assert(InRange(Value));
Assert(SizeOf(Result)<=SizeOf(Value));
Move(Value, Result, SizeOf(Result));
end;
class function TEnumeration<T>.ToString(Enum: T): string;
begin
Result := GetEnumName(TypeInfo, ToOrdinal(Enum));
end;
class function TEnumeration<T>.FromString(const S: string): T;
begin
Result := FromOrdinal(GetEnumValue(TypeInfo, S));
end;
class function TEnumeration<T>.MinValue: Integer;
begin
Assert(IsEnumeration);
Result := TypeData.MinValue;
end;
class function TEnumeration<T>.MaxValue: Integer;
begin
Assert(IsEnumeration);
Result := TypeData.MaxValue;
end;
class function TEnumeration<T>.InRange(Value: Integer): Boolean;
var
ptd: PTypeData;
begin
Assert(IsEnumeration);
ptd := TypeData;
Result := Math.InRange(Value, ptd.MinValue, ptd.MaxValue);
end;
class function TEnumeration<T>.EnsureRange(Value: Integer): Integer;
var
ptd: PTypeData;
begin
Assert(IsEnumeration);
ptd := TypeData;
Result := Math.EnsureRange(Value, ptd.MinValue, ptd.MaxValue);
end;
class function TRttiEnumerationType.GetName<T{: enum}>(AValue: T): string;
class function TRttiEnumerationType.GetValue<T{: enum}>(const AName: string): T;
S:= TRttiEnumerationType.GetName(myEnum);