delphi - 如何获取类型的枚举 [英] delphi - how to get type of enum

查看:214
本文介绍了delphi - 如何获取类型的枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如何从整数值获取枚举值,我有这个代码

 函数GetEnumValue(intValue:integer) :TMyType 
begin
if(ordValue> = Ord(Low(TMyType)))和(ordValue< = Ord(High(TMyType)))然后
result:= TMyType(ordValue )
else
raise Exception.Create('ordValue out of TMyType range');
结束

我有很多类似上面的类似代码,除了TMyType之外的许多枚举类型,我想封装代码到基类上的单一保护代码,所以继承的类可以使用它。



但是我不知道如何推广TMyType,所以我的代码可以检查它是否正确枚举类型或者另一个类型的对象



我不知道什么是枚举基类(对于所有对象类型的TObject或所有VCL类型的TControl),那么我可以检查像这样的代码

解决方案

没有像枚举类型的基础类型这样的东西,像TObject是类的基础。



如果您有支持泛型的Delphi版本,则可以使用以下帮助器将序数值的泛型转换为枚举值。

 使用
System.SysUtils,TypInfo;

类型
TEnumHelp< TEnum> = record
type
ETEnumHelpError = class(Exception);
类函数Cast(const Value:Integer):TEnum;静态的;
结束

类函数TEnumHelp< TEnum> .Cast(const Value:Integer):TEnum;
var
typeInf:PTypeInfo;
typeData:PTypeData;
begin
typeInf:= PTypeInfo(TypeInfo(TEnum));
if(typeInf = nil)或(typeInf ^ .Kind<> tkEnumeration)然后
raise ETEnumHelpError.Create('not a enumeration type');
typeData:= GetTypeData(typeInf);
if(Value< typeData ^ .MinValue)then
raise ETEnumHelpError.CreateFmt('%d is below min value [%d]',[Value,typeData ^ .MinValue])
else
if(Value> typeData ^ .MaxValue)then
raise ETEnumHelpError.CreateFmt('%d is above max value [%d]',[Value,typeData ^ .MaxValue]);
case Sizeof(TEnum)of
1:pByte(@Result)^:= Value;
2:pWord(@Result)^:= Value;
4:pCardinal(@Result)^:= Value;
结束
结束

示例:

 code>键入
TestEnum =(aA,bB,cC);

var
e:TestEnum;
...
e:= TEnumHelp< TestEnum> .Cast(2); // e = cC






有一个限制:



枚举不连续或不以零开头,
没有 RTTI TypeInfo信息。请参阅 固定枚举未返回的RTTI属性:是否为错误?


I know how to get enum value from integer value, and I have this code

function GetEnumValue(intValue:integer):TMyType
begin
   if(ordValue >= Ord(Low(TMyType)))and(ordValue <= Ord(High(TMyType)))then 
      result :=TMyType(ordValue)
   else 
      raise Exception.Create('ordValue out of TMyType range');
end;

I have similiar code like above in many place for many enum type other than TMyType, I want encapsulate that code to single protected code on base class, so inherited class can use it.

but I dont know how to generalize TMyType, so my code can check if it right enum type or another type object

I cant have a clue what a enum base class (like TObject for all of object type or TControl for all of VCL type), then I can check like that code

解决方案

There is no such thing as a base type for an enumeration type, like TObject is the base for classes.

If you have a Delphi version that supports generics, you can use following helper to make a generic cast from an ordinal value to an enumeration value.

uses
  System.SysUtils,TypInfo;

Type
  TEnumHelp<TEnum> = record
  type
    ETEnumHelpError = class(Exception);
    class function Cast(const Value: Integer): TEnum; static;
  end;

class function TEnumHelp<TEnum>.Cast(const Value: Integer): TEnum;
var
  typeInf  : PTypeInfo;
  typeData : PTypeData;
begin
  typeInf := PTypeInfo(TypeInfo(TEnum));
  if (typeInf = nil) or (typeInf^.Kind <> tkEnumeration) then
    raise ETEnumHelpError.Create('Not an enumeration type');
  typeData := GetTypeData(typeInf);
  if (Value < typeData^.MinValue) then
    raise ETEnumHelpError.CreateFmt('%d is below min value [%d]',[Value,typeData^.MinValue])
  else
  if (Value > typeData^.MaxValue) then
    raise ETEnumHelpError.CreateFmt('%d is above max value [%d]',[Value,typeData^.MaxValue]);
  case Sizeof(TEnum) of
    1: pByte(@Result)^ := Value;
    2: pWord(@Result)^ := Value;
    4: pCardinal(@Result)^ := Value;
  end;
end;

Example:

Type
  TestEnum = (aA,bB,cC);

var
  e : TestEnum;
...
e := TEnumHelp<TestEnum>.Cast(2);  // e = cC


There is one limitation:

Enumerations that are discontiguous or does not start with zero, have no RTTI TypeInfo information. See RTTI properties not returned for fixed enumerations: is it a bug?.

这篇关于delphi - 如何获取类型的枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆