注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

银河军团大本营

光荣的军团,永远的丰碑 <坚持原创>

 
 
 

日志

 
 

利用Delphi泛型将枚举和字符串相互转换  

2013-05-31 20:01:26|  分类: 编程小技巧 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

  Delphi2009开始支持泛型了,正好想写一个通用的东东来做枚举和字符串的相互转换,于是有了下面这个TEnumConvert类:

unit EnumConvert;

{*******************************************************************************
* 枚举/字符串转换通用类 *
* *
* 功能: 将枚举转换为字符串,及将字符串转换为枚举 *
* 实现: 2013.5.31 *
* 以前在枚举和字符串之间相互转换时,往往每个枚举类型都要单独实现,好 *
* 在Delphi2009之后提供了泛型,现在终于可以实现一个通用的转换类了。 *
* 以下代码是从Rtti.pas中TRttiEnumerationType类的GetName/GetValue函数 *
* 复制而来,用起来感觉方便多了。 *
* 代码在Delphi 2010/XE2中测试通过。 *
* Delphi的源代码中隐藏了不少好东西啊,看来以后要多多挖掘^o^ *
* EMail: iamdream%yeah.net (% -> @) *
*******************************************************************************}

interface

{$IFNDEF UNICODE}Sorry, Only Support Unicode Version!{$ENDIF}

uses
SysUtils, Classes, TypInfo, SysConst{, Rtti};

type
TEnumConvert<T> = class
public
class function StrToEnumType(const S: string): T; overload;
class function StrToEnumType(const S: string; Default: T): T; overload;
class function EnumToString(Value: T): string;
end;

implementation

{ TEnumConvert }

class function TEnumConvert<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 TEnumConvert<T>.StrToEnumType(const S: string; Default: T): T;
begin
if S <> '' then begin
Result := StrToEnumType(S);
end else begin
Result := Default;
end;
end;

class function TEnumConvert<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);
//Result := TValue.From<T>(Value).ToString; //利用TValue转换
end;

end.

  这下方便了,一个类可以处理所有的枚举了!用起来也很简单:

uses DB;
//...
var
ft: TFieldType;
s: string;
begin
ft := ftFloat;
s := TEnumConvert<TFieldType>.EnumToString(ft);
ShowMessage('EnumToString: ' + s);
ft := TEnumConvert<TFieldType>.StrToEnumType(s);
if ft = ftFloat then begin
ShowMessage('StrToEnumType is OK.');
end else begin
ShowMessage('StrToEnumType is error.');
end;

  需要注意的是,如果枚举定义时指定了数值(比如“type TMyEnum = (meOk = 1, meError = 5, meTest=7);”),则不可以用TypInfo.pas里的方法来转换?!

  当然,如果只是将枚举转换为字符串,可以直接利用Rtti.pas里的TValue来做,比如上面例子中将ft(TFieldType)转换为字符串就可以这样写:TValue.From<TFieldType>(ft).ToString。

  评论这张
 
阅读(1111)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018