Delphi 如何更改代码以获得正确的枚举名称值?
我正在尝试使用RTTI获取枚举名称值 我的目标是使用字符串值从Enum2(迭代器)中选定的枚举名称值获取Enum1(Tsex)中相应的枚举名称值 下面是我已经实现的代码。我使用的是Delphi7Delphi 如何更改代码以获得正确的枚举名称值?,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
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太短。不管你有什么问题,这都不是解决办法。我喜欢你的答案。这是一个愚蠢的错误,单块/复合块。你解释了这一点,但接着又说了很多。干得好!谢谢,事实上我正试着以你为榜样@我知道这里禁止说谢谢,但我真的忍不住了,谢谢你今年最好的回答,我喜欢你的回答。这是一个愚蠢的错误,单块/复合块。你解释了这一点,但接着又说了很多。干得好!谢谢,事实上我正试着以你为榜样@我知道这里禁止说谢谢,但我真的忍不住了,谢谢你给我今年最好的答案