Entre as muitas novidades da versão 2005 do Delphi está o novo comando for-in-do, presente na nova Delphi Language. Como muitos já devem saber, esta variação do tradicional loop for permite percorrer todos os elementos de uma coleção sem ser necessário especificar o início e o fim da iteração. Assim, códigos de loops tornam-se mais simples de serem escritos. Compare:
var
Colecao: TStringList;
I: Integer;
begin
Colecao := ObterAlgumaColecao;
for I := 0 to Colecao.Count – 1 do
ShowMessage(Colecao[I]);
var
Colecao : TStringList;
Item : string;
begin
Colecao := ObterAlgumaColecao;
for Item in Colecao do
ShowMessage(Item);
Bem mais fácil, não?
O que a maioria (ainda) não sabe, é que nem toda coleção pode ser usada com o loop for-in-do. Para usufruir desde novo recurso da Delphi Language, é necessário fazer algumas adaptações na classe que se pretende utilizar, e é isso que veremos neste artigo.
Atributos necessários
Para adaptar a classe ao novo loop, deve-se seguir os seguintes passos:
- A classe deve ter um método, de visibilidade public, chamado GetEnumerator(). Esta função deve retornar uma classe, uma interface ou um record;
- O tipo retornado por GetEnumerator() deve possuir um método (public) chamado MoveNext(), que deve retornar um tipo Boolean;
- A classe, interface ou record retornado por GetEnumerator() deve conter uma propriedade pública somente-leitura chamada Current, do mesmo tipo de dado contido na coleção.
Mãos à obra!
Nada como um exemplo para entendermos melhor como se implementar a teoria acima. Então, no Delphi 2005, clique em File->New->Unit – Delphi for Win32. Em seguida, digite o código abaixo:
TMinhaArray = array of string;
TMeuItem = class
private
Values: TMinhaArray;
Index: Integer;
public
constructor Create;
function GetCurrent: string;
function MoveNext : Boolean;
property Current : string read GetCurrent;
end;
TMinhaColecao = class
public
function GetEnumerator: TMeuItem;
end;
Aqui apenas declaramos as classes que precisaremos implementar. Observe os métodos criados, com nomes compatíveis às especificações mencionadas anteriormente.
Implemente tudo com Ctrl + Shift + C. Para o único construtor existente, digite o código a seguir:
constructor TMeuItem.Create;
begin
inherited Create;
Values := TMinhaArray.Create('Borland', 'Delphi', '2005');
Index := -1;
end;
Para o método GetCurrent, digite apenas:
function TMeuItem.GetCurrent: string;
begin
Result := Values[Index];
end;
E, por fim, para MoveNext:
function TMeuItem.MoveNext: Boolean;
begin
if Index < High(Values) then
begin
Inc(Index);
Result := True;
end
else
Result := False;
end;
O código acima simplesmente retorna o próximo item da coleção.
Agora, resta apenas o método GetEnumerator da classe TMinhaColecao, que é muito simples, como visto abaixo:
{ TMinhaColecao }
function TMinhaColecao.GetEnumerator: TMeuItem;
begin
Result := TMeuItem.Create;
end;
Salve a unit com o nome de MinhaColecao.pas. Inicie então uma nova aplicação VCL no Delphi 2005 (File->New->VCL Forms Application – Win32), coloque um botão, declare nossa unit na cláusula uses da seção implementation e digite o código a seguir no evento OnClick do botão:
uses MinhaColecao;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Colecao: TMinhaColecao;
S: string;
begin
Colecao := TMinhaColecao.Create;
for S in Colecao do
ShowMessage(S);
Colecao.Free;
end;
Rode a aplicação e veja o loop for-in-do acessando nossa classe.
Conclusão
Como pudemos ver, é bem simples adaptar nossas próprias coleções para serem compatíveis com o novo comando for-in presente no Delphi 2005. Use-o e abuse-o em suas aplicações! Um forte abraço a todos e até o próximo artigo.