在 Delphi 中迭代枚举中的项目
我想迭代枚举中的项目。
我希望能够这样说:
type
TWeekdays = (wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday);
...
elementCount := GetElementCount(TypeInfo(TWeekDays));
for i := 0 to elementCount - 1 do begin
ShowMessage(GetEnumName(TypeInfo(TWeekdays),i));
end;
我能得到的最接近的是:
function MaxEnum(EnumInfo: PTypeInfo): integer;
const
c_MaxInt = 9999999;
var
i: integer;
s: string;
begin
//get # of enum elements by looping thru the names
//until we get to the end.
for i := 0 to c_MaxInt do begin
s := Trim(GetEnumName(EnumInfo,i));
if 0 = Length(s) then begin
Result := i-1;
Break;
end;
end;
end;
我这样使用:
procedure TForm1.BitBtn1Click(Sender: TObject);
var
i, nMax: integer;
begin
ListBox1.Clear;
nMax := MaxEnum(TypeInfo(TWeekdays));
for i := 0 to nMax do begin
ListBox1.Items.Add(GetEnumName(TypeInfo(TWeekdays),i));
end;
end;
效果很好,除了我得到的列表看起来像这样(注意最后两项) :
wdMonday
wdTuesday
wdWednesday
wdThursday
wdFriday
Unit1
'@'#0'ôÑE'#0#0#0#0#0#0#0#0#0#0#0#0#0 <more garbage characters>
最后的两条显然不是我想要的。
有没有更好的方法来迭代枚举类型的元素?
如果不是,那么可以安全地假设使用我当前的方法总是恰好有两个额外项目吗?显然,其中之一是单位名称......但是“@”符号是做什么的?它真的是垃圾,还是更多类型信息?
我正在使用Delphi 2007。 感谢您的任何见解。
I want to iterate through the items in an enumeration.
I'd like to be able to say something like this:
type
TWeekdays = (wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday);
...
elementCount := GetElementCount(TypeInfo(TWeekDays));
for i := 0 to elementCount - 1 do begin
ShowMessage(GetEnumName(TypeInfo(TWeekdays),i));
end;
The closest I've been able to come is this:
function MaxEnum(EnumInfo: PTypeInfo): integer;
const
c_MaxInt = 9999999;
var
i: integer;
s: string;
begin
//get # of enum elements by looping thru the names
//until we get to the end.
for i := 0 to c_MaxInt do begin
s := Trim(GetEnumName(EnumInfo,i));
if 0 = Length(s) then begin
Result := i-1;
Break;
end;
end;
end;
Which I use like this:
procedure TForm1.BitBtn1Click(Sender: TObject);
var
i, nMax: integer;
begin
ListBox1.Clear;
nMax := MaxEnum(TypeInfo(TWeekdays));
for i := 0 to nMax do begin
ListBox1.Items.Add(GetEnumName(TypeInfo(TWeekdays),i));
end;
end;
That works well, except the list I get looks like this (notice the last two items):
wdMonday
wdTuesday
wdWednesday
wdThursday
wdFriday
Unit1
'@'#0'ôÑE'#0#0#0#0#0#0#0#0#0#0#0#0#0 <more garbage characters>
The two items at the end are obviously not what I want.
Is there a better way to iterate through the elements of an enumerated type?
If not, then is it safe to assume that there will always be exactly two extra items using my current method? Obviously one is the Unit name... but what is the "@" symbol doing? Is it really garbage, or is it more type information?
I'm using Delphi 2007.
Thanks for any insights.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
简单的:
Simple:
当使用特殊枚举时,它比这要复杂得多......让我们看看复杂枚举定义的真正 100% 工作解决方案:
注意:
为什么这样做?:
TmyEnumType
分配给它时,它不是连续的技巧:
如果您尝试其他(逻辑人类方式)思考)它不会工作(无论是否使用for循环,while循环,重复直到等):
这是我自己在Turbo Delphi 2006上测试过的。
It is quite more complex than that, when used special enumerations... let's see a really 100% working solution for a complex enumerated definition:
Notes:
Why it has been done like that?:
TmyEnumType
assign to it (9-2+1=8) elemments (from lower one (2) to higher one (9), so valid values for such type are from ordinal 2 to ordinal 9The Trick:
If you try this other (logical human way of thinking) it will not work (no matter if use for loop, while loop, repeat until, etc):
That is what i have tested by my own on Turbo Delphi 2006.
您可以使用 Succ(x) 和 Pred(x) 循环遍历枚举。但请记住检查边界,这样您就不会在枚举中的最后一个元素上尝试 Succ(x)!
例子:
You can use Succ(x) and Pred(x) to loop through an enumeration. But remember to check for boundaries so you don't try Succ(x) on the last element in the enumeration!
Example:
我制作了一个 EnumerationEnumerator,以便您可以在 Delphi 的“for ... in”语句中使用它。
然而,当时它有时会产生内部编译器错误。
编辑:
设法让它在Delphi 2007及更高版本中工作,请参阅这篇博客文章(及其下非常有趣的讨论)。
I made an EnumerationEnumerator so you could use it in the 'for ... in' statement in Delphi.
However, back then it would sometimes generate internal compiler errors.
Edit:
Managed to get it to work in Delphi 2007 and up, see this blog article (and the quite interesting discussion under it).
此示例在 Delphi Sydney (10.4)
(http://www.delphibasics. co.uk/Article.asp?Name=Sets )
This example compiles on Delphi Sydney (10.4)
( http://www.delphibasics.co.uk/Article.asp?Name=Sets )