gpt4 book ai didi

delphi - 如何使用 "for/in"查找另一个组件内部的组件?

转载 作者:行者123 更新时间:2023-12-03 15:41:43 27 4
gpt4 key购买 nike

我正在重构组件代码,发现以下代码:

procedure TMenuToolbarButton.ClearActivation;
var
i: Integer;
begin
for i := 0 to Self.Parent.ComponentCount -1 do
begin
if (Self.Parent.Components[i] is TMenuToolbarButton) then
begin
(Self.Parent.Components[i] as TMenuToolbarButton).FActivatedImage.Visible := False;
(Self.Parent.Components[i] as TMenuToolbarButton).FActivatedImageGrowLeft.Visible := False;
end;
end;
end;

我今天工作得很好,但我想在这个方法中使用 for/in,如下所示:

procedure TMenuToolbarButton.ClearActivation;
var
MyMenuToolbarButton: TMenuToolbarButton;
begin
for MyMenuToolbarButton in Self.Parent do
begin
MyMenuToolbarButton.FActivatedImage.Visible := False;
MyMenuToolbarButton.FActivatedImageGrowLeft.Visible := False;
end;
end;

我已经尝试使用 Generics.Collections 类型转换 Self.Parent像这样:TObjectList<TMenuToolbarButton>(Self.Parent)

所以,我想知道是否有更好的方法让工作代码更“优雅”

最佳答案

ParentTWinControl,而不是 TObjectList,因此您尝试的类型转换无效。

您不能直接将 for.. in 循环与 Components 属性一起使用,因为它不是满足任何 documented requirements 的可迭代容器。 :

Delphi supports for-element-in-collection style iteration over containers. The following container iteration patterns are recognized by the compiler:

  • for Element in ArrayExpr do Stmt;

  • for Element in StringExpr do Stmt;

  • for Element in SetExpr do Stmt;

  • for Element in CollectionExpr do Stmt;

  • for Element in Record do Stmt;

Components 属性不是数组、字符串、集合、集合或记录,因此无法通过 for..in 进行迭代> 循环。

但是,TComponent 本身满足可迭代集合的记录要求:

To use the for-in loop construct on a class or interface, the class or interface must implement a prescribed collection pattern. A type that implements the collection pattern must have the following attributes:

  • The class or interface must contain a public instance method called GetEnumerator(). The GetEnumerator() method must return a class, interface, or record type.

  • The class, interface, or record returned by GetEnumerator() must contain a public instance method called MoveNext(). The MoveNext() method must return a Boolean. The for-in loop calls this method first to ensure that the container is not empty.

  • The class, interface, or record returned by GetEnumerator() must contain a public instance, read-only property called Current. The type of the Current property must be the type contained in the collection.

TComponent 有一个公共(public) GetEnumerator()返回 TComponentEnumerator 的方法在内部迭代 Components 属性的对象。但是,由于该属性处理 TComponent 对象,因此您仍然需要在循环内手动对它们进行类型转换。

试试这个:

procedure TMenuToolbarButton.ClearActivation;
var
//i: Integer;
Comp: TComponent;
Btn: TMenuToolbarButton;
begin
//for i := 0 to Self.Parent.ComponentCount -1 do
for Comp in Self.Parent do
begin
//Comp := Self.Parent.Components[i];
if Comp is TMenuToolbarButton then
begin
Btn := TMenuToolbarButton(Comp);
Btn.FActivatedImage.Visible := False;
Btn.FActivatedImageGrowLeft.Visible := False;
end;
end;
end;

因此,在这种情况下,使用 for..in 循环并不会比传统的 for..to 循环真正获得任何有用的东西。

关于delphi - 如何使用 "for/in"查找另一个组件内部的组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57060358/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com