Delphi 如何更改代码以获得正确的枚举名称值?

Delphi 如何更改代码以获得正确的枚举名称值?,delphi,enums,delphi-7,rtti,Delphi,Enums,Delphi 7,Rtti,我正在尝试使用RTTI获取枚举名称值 我的目标是使用字符串值从Enum2(迭代器)中选定的枚举名称值获取Enum1(Tsex)中相应的枚举名称值 下面是我已经实现的代码。我使用的是Delphi7 uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs,typinfo; type Tsex = (homme,femme); iterator = (H,F); TFor

我正在尝试使用RTTI获取枚举名称值

我的目标是使用字符串值从Enum2(迭代器)中选定的枚举名称值获取Enum1(Tsex)中相应的枚举名称值

下面是我已经实现的代码。我使用的是Delphi7

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs,typinfo;

type

 Tsex = (homme,femme);
 iterator = (H,F);

TForm1 = class(TForm)
  procedure FormShow(Sender: TObject);
private
 { Déclarations privées }
 public
 { Déclarations publiques }
end;

var
  Form1: TForm1;

implementation

 {$R *.dfm}


 procedure TForm1.FormShow(Sender: TObject);
  var
    i : integer;
    OT: Tsex;
    FT: iterator;
 begin
   i:=0;
   OT := Low(Tsex);
   for FT := Low(iterator) to High(iterator) do
     if GetEnumName(TypeInfo(iterator), Ord(FT)) = 'F' then
     begin
       showmessage(GetEnumName(TypeInfo(Tsex), Ord(OT)));
     end;
     i:=i+1;
     OT:=Succ(OT);
   end;
当我使用
H
作为字符串时,我得到
homme
,但当我使用
F
时,我也得到
homme
。但这需要解决
femme

问题: 代码中的问题是,在的之后缺少一个开始,这会导致在迭代完成后,
i
的增量和
OT
的赋值

您需要更改的是:

var
  i : integer;
  OT: Tsex;
  FT: iterator;
begin
  i:=0;
  OT := Low(Tsex);
  for FT := Low(iterator) to High(iterator) do
  begin // <- Add begin here
    if GetEnumName(TypeInfo(iterator), Ord(FT)) = 'F' then
    begin
      showmessage(GetEnumName(TypeInfo(Tsex), Ord(OT)));
    end;
    i:=i+1;
    OT:=Succ(OT);
  end;
 end; // <- Add end; here

当您的枚举类型仅包含两个值,并且将来不太可能有其他值时,您可以使用良好的旧if-else运算符:

function GetMyEnumValue(const aDBValue: string): TSex;
begin
  if SameText(aDBValue, 'F') then
  begin
    Result := femme;
  end else
  begin
    Result := homme;
  end;
end;
简而言之,避免过度工程化的问题

注意:我们使用
string
存储字符值,并使用
SameText
进行比较,因为它不区分大小写。另外,如果将来您改变了在DB中存储值的方式,它允许您比较多个字符的文本


忠告: 我也建议你咨询一下

这似乎和问题无关,但遵循缩进的良好实践有助于避免此类问题

命名类型和变量的指南也很重要。在其他情况下,它们同样可以帮助您解决问题。

问题: 代码中的问题是,在的之后缺少一个开始,这会导致在迭代完成后,
i
的增量和
OT
的赋值

您需要更改的是:

var
  i : integer;
  OT: Tsex;
  FT: iterator;
begin
  i:=0;
  OT := Low(Tsex);
  for FT := Low(iterator) to High(iterator) do
  begin // <- Add begin here
    if GetEnumName(TypeInfo(iterator), Ord(FT)) = 'F' then
    begin
      showmessage(GetEnumName(TypeInfo(Tsex), Ord(OT)));
    end;
    i:=i+1;
    OT:=Succ(OT);
  end;
 end; // <- Add end; here

当您的枚举类型仅包含两个值,并且将来不太可能有其他值时,您可以使用良好的旧if-else运算符:

function GetMyEnumValue(const aDBValue: string): TSex;
begin
  if SameText(aDBValue, 'F') then
  begin
    Result := femme;
  end else
  begin
    Result := homme;
  end;
end;
简而言之,避免过度工程化的问题

注意:我们使用
string
存储字符值,并使用
SameText
进行比较,因为它不区分大小写。另外,如果将来您改变了在DB中存储值的方式,它允许您比较多个字符的文本


忠告: 我也建议你咨询一下

这似乎和问题无关,但遵循缩进的良好实践有助于避免此类问题


命名类型和变量的指南也很重要。在其他情况下,它们同样可以为您节省时间。

在循环的每次迭代过程中,调试器会告诉您
OT
的值是什么?我的作用是什么?为什么有两种枚举类型?应该只有一个。不要定义额外的枚举类型只是为了有短名称和长名称。使用常量数组。我认为您可能遗漏的一点是,当您有一个枚举时,您可以调用枚举名称,就像它是一个返回枚举值的函数一样,例如OT:=TSex(I)。FormShow中只需要一个变量就可以完成您现在所做的事情。@DavidHeffernan这只是我得到的一个想法,我需要它来工作(自我挑战),我真正的目标是从数据库中读取字符串,而在我的数据库中,我只有Enum中的缩写('E','F')但在我的表格中,我想得到所有枚举中所有E对应的值或F值。你提出的解决方案不是前进的方向。您确实不希望枚举名F和H太短。无论您遇到什么问题,这都不是解决方案。在循环的每次迭代期间,调试器会告诉您
OT
的值是什么?我的目的是什么?为什么有两种枚举类型?应该只有一个。不要定义额外的枚举类型只是为了有短名称和长名称。使用常量数组。我认为您可能遗漏的一点是,当您有一个枚举时,您可以调用枚举名称,就像它是一个返回枚举值的函数一样,例如OT:=TSex(I)。FormShow中只需要一个变量就可以完成您现在所做的事情。@DavidHeffernan这只是我得到的一个想法,我需要它来工作(自我挑战),我真正的目标是从数据库中读取字符串,而在我的数据库中,我只有Enum中的缩写('E','F')但在我的表格中,我想得到所有枚举中所有E对应的值或F值。你提出的解决方案不是前进的方向。您确实不希望枚举名F和H太短。不管你有什么问题,这都不是解决办法。我喜欢你的答案。这是一个愚蠢的错误,单块/复合块。你解释了这一点,但接着又说了很多。干得好!谢谢,事实上我正试着以你为榜样@我知道这里禁止说谢谢,但我真的忍不住了,谢谢你今年最好的回答,我喜欢你的回答。这是一个愚蠢的错误,单块/复合块。你解释了这一点,但接着又说了很多。干得好!谢谢,事实上我正试着以你为榜样@我知道这里禁止说谢谢,但我真的忍不住了,谢谢你给我今年最好的答案