How can I get an enumeration's valid ranges using RTTI or TypeInfo in Delphi

佐手、 提交于 2021-02-07 08:31:54

问题


I am using RTTI in a test project to evaluate enumeration values, most commonly properties on an object. If an enumeration is out of range I want to display text similar to what Evaluate/Modify IDE Window would show. Something like "(out of bound) 255".

The sample code below uses TypeInfo to display the problem with a value outside the enumeration as an Access Violation when using GetEnumName. Any solution using RTTI or TypeInfo would help me, I just don't know the enumerated type in my test code

program Project60;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,  TypInfo;

Type
  TestEnum = (TestEnumA, TestEnumB, TestEnumC);

const
  TestEnumUndefined = TestEnum(-1);

  procedure WriteEnum(const ATypeInfo: PTypeInfo; const AOrdinal: Integer);
  begin
    WriteLn(Format('Ordinal: %d = "%s"', [AOrdinal, GetEnumName(ATypeInfo, AOrdinal)]));
  end;


var
  TestEnumTypeInfo: PTypeInfo;
begin

  try
    TestEnumTypeInfo := TypeInfo(TestEnum);

    WriteEnum(TestEnumTypeInfo, Ord(TestEnumA));
    WriteEnum(TestEnumTypeInfo, Ord(TestEnumB));
    WriteEnum(TestEnumTypeInfo, Ord(TestEnumC));
    WriteEnum(TestEnumTypeInfo,  Ord(TestEnumUndefined));   //AV

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  ReadLn;
end.

回答1:


Use GetTypeData() to get more detailed information from a PTypeInfo , eg:

procedure WriteEnum(const ATypeInfo: PTypeInfo; const AOrdinal: Integer);
var
  LTypeData: PTypeData;
begin
  LTypeData := GetTypeData(ATypeInfo);
  if (AOrdinal >= LTypeData.MinValue) and (AOrdinal <= LTypeData.MaxValue) then
    WriteLn(Format('Ordinal: %d = "%s"', [AOrdinal, GetEnumName(ATypeInfo, AOrdinal)]))
  else
    WriteLn(Format('Ordinal: %d (out of bound)', [AOrdinal]));
end;


来源:https://stackoverflow.com/questions/51899181/how-can-i-get-an-enumerations-valid-ranges-using-rtti-or-typeinfo-in-delphi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!