如何更改我的代码以获得正确的枚举名称值?
How to change my code to get the correct enumerate name value?
我正在尝试使用 RTTI 获取枚举名称值。
我的objective是使用字符串值从Enum2(iterator)中选择的枚举名称值中获取Enum1(Tsex)中对应的枚举名称值。
这是我实现的代码。我正在使用 Delphi 7.
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
.
问题:
您的代码中的问题是您在 for
之后缺少 begin
,这会导致 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
替代解决方案:
正如 David 指出的那样,最好使用数组将另一组值映射到您的枚举。像这样:
type
TSex = (homme, femme);
const
SexDBValues: array [TSex] of string =
('H', 'F');
type
TForm1 = class(TForm)
procedure FormShow(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function GetMyEnumValue(const aDBValue: string): TSex;
var
value: TSex;
begin
for value := Low(TSex) to High(TSex) do
begin
if SameText(SexDBValues[value], aDBValue) then
begin
Result := value;
Exit;
end;
end;
end;
procedure TForm1.FormShow(Sender: TObject);
var
value: TSex;
begin
value := GetMyEnumValue('H');
ShowMessage(GetEnumName(TypeInfo(TSex), Ord(value)));
end;
当你的枚举类型只包含两个值,并且将来不太可能有额外的值时,你可以只使用旧的 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
来比较它,因为它比较文本时不区分大小写。此外,它允许您比较多个字符的文本,以防将来您改变主意在数据库中存储值的方式。
建议:
我还建议您咨询 Delphi Coding Style Guide。
这似乎与问题无关,但遵循缩进的良好做法有助于避免此类问题。
命名类型和变量的准则也很重要。他们在其他情况下同样会救你。
我正在尝试使用 RTTI 获取枚举名称值。
我的objective是使用字符串值从Enum2(iterator)中选择的枚举名称值中获取Enum1(Tsex)中对应的枚举名称值。
这是我实现的代码。我正在使用 Delphi 7.
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
.
问题:
您的代码中的问题是您在 for
之后缺少 begin
,这会导致 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
替代解决方案:
正如 David 指出的那样,最好使用数组将另一组值映射到您的枚举。像这样:
type
TSex = (homme, femme);
const
SexDBValues: array [TSex] of string =
('H', 'F');
type
TForm1 = class(TForm)
procedure FormShow(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function GetMyEnumValue(const aDBValue: string): TSex;
var
value: TSex;
begin
for value := Low(TSex) to High(TSex) do
begin
if SameText(SexDBValues[value], aDBValue) then
begin
Result := value;
Exit;
end;
end;
end;
procedure TForm1.FormShow(Sender: TObject);
var
value: TSex;
begin
value := GetMyEnumValue('H');
ShowMessage(GetEnumName(TypeInfo(TSex), Ord(value)));
end;
当你的枚举类型只包含两个值,并且将来不太可能有额外的值时,你可以只使用旧的 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
来比较它,因为它比较文本时不区分大小写。此外,它允许您比较多个字符的文本,以防将来您改变主意在数据库中存储值的方式。
建议:
我还建议您咨询 Delphi Coding Style Guide。
这似乎与问题无关,但遵循缩进的良好做法有助于避免此类问题。
命名类型和变量的准则也很重要。他们在其他情况下同样会救你。