首页 > 代码库 > 用泛型实现对枚举的通用处理
用泛型实现对枚举的通用处理
写代码的时候遇到一个问题,想写一个通用方法来实现对枚举的类型的操作,如获取枚举的项的列表,获取一个枚举值的索引等等,
本来以为很简单,写一个函数:
function GetEnumNames(枚举类): TArray<string>
结果发现这个参数怎么搞也搞不对,不知道传一个什么样的参数可以支持所有枚举类型,因为函数内会用TypeInfo。
后来想到用泛型来传入枚举类来处理,果然成功了。
/// <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;implementationuses 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;
通过这次尝试,加深了对泛型的理解。
用泛型实现对枚举的通用处理
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。