uses TypInfo, SysUtils, SysConst; type TEnumHelper = record class function TryGetEnumName<T: record>(Value: T; out S: String): Boolean; static; class function GetEnumName<T: record>(Value: T): String; static; class function TryGetEnumValue<T: record>(const Name: String; out Enum: T): Boolean; overload; static; class function GetEnumValue<T: record>(const Name: String): T; overload; static; class function TryGetEnumValue<T: record>(Value: Integer; out Enum: T): Boolean; overload; static; class function GetEnumValue<T: record>(Value: Integer): T; overload; static; end; class function TEnumHelper.TryGetEnumName<T>(Value: T; out S: String): Boolean; var P: PTypeInfo; IValue: Integer; begin Result := False; S := ''; P := TypeInfo(T); if (P = nil) or (P^.Kind <> tkEnumeration) then begin Exit; end; IValue := 0; Move(Value,IValue,SizeOf(T)); S := TypInfo.GetEnumName(P,IValue); Result := True; end; class function TEnumHelper.GetEnumName<T>(Value: T): String; var P: PTypeInfo; IValue: Integer; begin P := TypeInfo(T); if (P = nil) or (P^.Kind <> tkEnumeration) then begin raise EInvalidOpException.CreateRes(@SVarNotImplemented); end; IValue := 0; Move(Value,IValue,SizeOf(T)); Result := TypInfo.GetEnumName(P,IValue); end; class function TEnumHelper.TryGetEnumValue<T>(const Name: String; out Enum: T): Boolean; var P: PTypeInfo; IValue: Integer; begin Result := False; Enum := Default(T); P := TypeInfo(T); if (P = nil) or (P^.Kind <> tkEnumeration) then begin Exit; end; IValue := TypInfo.GetEnumValue(P,Name); with GetTypeData(P)^ do begin if (IValue < MinValue) or (IValue > MaxValue) then begin Exit; end; end; Move(IValue,Enum,SizeOf(T)); Result := True; end; class function TEnumHelper.GetEnumValue<T>(const Name: String): T; var P: PTypeInfo; IValue: Integer; begin Result := Default(T); P := TypeInfo(T); if (P = nil) or (P^.Kind <> tkEnumeration) then begin raise EInvalidOpException.CreateRes(@SVarNotImplemented); end; IValue := TypInfo.GetEnumValue(P,Name); with GetTypeData(P)^ do begin if (IValue < MinValue) or (IValue > MaxValue) then begin raise ERangeError.CreateRes(@SRangeError); end; end; Move(IValue,Result,SizeOf(T)); end; class function TEnumHelper.TryGetEnumValue<T>(Value: Integer; out Enum: T): Boolean; var P: PTypeInfo; begin Result := False; Enum := Default(T); P := TypeInfo(T); if (P = nil) or (P^.Kind <> tkEnumeration) then begin Exit; end; with GetTypeData(P)^ do begin if (Value < MinValue) or (Value > MaxValue) then begin Exit; end; end; Move(Value,Enum,SizeOf(T)); Result := True; end; class function TEnumHelper.GetEnumValue<T>(Value: Integer): T; var P: PTypeInfo; begin Result := Default(T); P := TypeInfo(T); if (P = nil) or (P^.Kind <> tkEnumeration) then begin raise EInvalidOpException.CreateRes(@SVarNotImplemented); end; with GetTypeData(P)^ do begin if (Value < MinValue) or (Value > MaxValue) then begin raise ERangeError.CreateRes(@SRangeError); end; end; Move(Value,Result,SizeOf(T)); end;こんな感じで使います。
var S: String; begin if TEnumHelper.TryGetEnumName(0,S) = True then // Error (0 is not enumeration) begin Label1.Caption := S; end else begin Label1.Caption := '(Error)'; end; S := TEnumHelper.GetEnumName(taLeftJustify); // taLeftJustify -> 'taLeftJustify' Label2.Caption := S; S := TEnumHelper.GetEnumName(False); // False -> 'False' Label3.Caption := S; end;元ねたはDelphi XE2 Foundations。
→列挙型と列挙子名(文字列)または整数の相互変換(ジェネリックス版) (Gist)
0 件のコメント:
コメントを投稿