# 编码笔记

• 随笔 - 36
• 文章 - 3
• 评论 - 14
• 引用 - 0

## 用泛型实现对枚举的通用处理

function GetEnumNames(枚举类): TArray<string>

  /// <summary> 针对枚举类型的一组功能函数 </summary>
TEnumEX<T> = class
public
/// <summary> 把字符串转成枚举的值 </summary>
class function StrToEnumType(const S: string): T; overload;
/// <summary> 把字符串转成枚举的值 </summary>
class function StrToEnumType(const S: string; Default: T): T; overload;
/// <summary> 把枚举的值转成字符串 </summary>
class function EnumToString(Value: T): string;
/// <summary> 获取枚举类型的项列表 </summary>
class function GetEnumNames : TArray<string>;
/// <summary> 获取枚举值的序号 </summary>
class function GetEnumOrd(const S: string) : Integer;
end;

implementation

uses
RTTI,SysConst,uLayoutConst;

{ TEnumConvert<T> }

class function TEnumEX<T>.EnumToString(Value: T): string;
var
v: Integer;
begin
case PTypeInfo(TypeInfo(T))^.Kind of
tkEnumeration:
case TypInfo.GetTypeData(TypeInfo(T))^.OrdType of
otUByte, otSByte: v := PByte(@Value)^;
otUWord, otSWord: v := PWord(@Value)^;
otULong, otSLong: v := PInteger(@Value)^;
end;
else
raise EInvalidCast.CreateRes(@SInvalidCast);
end;
Result := TypInfo.GetEnumName(TypeInfo(T), v);
end;

class function TEnumEX<T>.StrToEnumType(const S: string): T;
begin
case PTypeInfo(TypeInfo(T))^.Kind of
tkEnumeration:
case TypInfo.GetTypeData(TypeInfo(T))^.OrdType of
otUByte, otSByte: PByte(@Result)^ := GetEnumValue(TypeInfo(T), S);
otUWord, otSWord: PWord(@Result)^ := GetEnumValue(TypeInfo(T), S);
otULong, otSLong: PInteger(@Result)^ := GetEnumValue(TypeInfo(T), S);
end;
else
raise EInvalidCast.CreateRes(@SInvalidCast);
end;
end;

class function TEnumEX<T>.GetEnumNames: TArray<string>;
var
p: PTypeData;
i: Integer;
s: String;
pt: PTypeInfo;
begin
pt := TypeInfo(T);
p := GetTypeData(TypeInfo(T));
SetLength(Result, p.MaxValue+1);
for i := p.MinValue to p.MaxValue do
begin
S := GetEnumName(pt,i);
Result[i] := S;
end;
end;

class function TEnumEX<T>.GetEnumOrd(const S: string): Integer;
begin
case PTypeInfo(TypeInfo(T))^.Kind of
tkEnumeration:
Result := GetEnumValue(TypeInfo(T), S);
else
raise EInvalidCast.CreateRes(@SInvalidCast);
end;
end;

class function TEnumEX<T>.StrToEnumType(const S: string; Default: T): T;
begin
if S <> '' then begin
Result := StrToEnumType(S);
end else begin
Result := Default;
end;
end;

var
s : string;
ss : TArray<string>;
begin
inherited;
ss := TEnumEX<TBIEditUIControl>.GetEnumNames;
for s in ss do
begin
ShowMessage(s);
end;
end;

posted on 2014-09-18 19:59  封三郎  阅读(...)  评论(...编辑  收藏