Con
Delphi 2005 se ha introducido la posibilidad de usar el operador in en los bucles for para las coleccione, los arrays(vectores), los conjuntos y las cadenas. Esto funciona en las aplicaciones para Win32 como para las de .Net.
Un ejemplo es:
var
S : String;
begin
for S in Memo1.Lines do
ListBox1.Items.Add(S);
end;
Es bastante mas util que la forma en que se hacia antes.
Para poder usar este operador en nuestras clases de coleciones tenemos que hacer lo siguiente:
- Tenemos que crear una clase o interfaz que haga de enumerador. Esta clase enumerador debe tener un funcion publica llamada MoveNext que devuelva un boolean y una propiedad que se llama Current que devuelve el objeto que estamos usando.
- En la clase de coleccion declarar un metodo publico GetEnumerator, que devuelva una instacia de esta clase enumerador que hemos creado.
Veamos un ejemplo:
Se define una clase:
TPersona = class
Nombre: String;
FechaDeNacimiento: TDateTime;
Sexo : Char;
constructor Create (ANombre: String; AFecha: TDateTime; ASexo: Char);
end;
Se define una coleccion:
TGente = class
strict private // nuevo modo de acceso a las clases
fLista : TList;
function GetCount: Integer;
function GetPersona(i: Integer): TPersona;
procedure SetPersona(i: Integer; const Value: TPersona);
public
function GetEnumerator: TGenteEnumerator;
function Add (Persona: TPersona): Integer;
procedure Delete (i: Integer);
property Person [i: Integer] : TPersona read GetPersona write SetPersona; default;
property Count: Integer read GetCount;
end;
Se define el enumerador
TGenteEnumerator = class
strict private
fPosicion: Integer;
fGente : TGente;
public
constructor Create (Lista : TGente);
function GetCurrent: TPersona;
function MoveNext :Boolean;
property Current : TPerson read GetCurrent;
end;
La implementacion de los metodos del enumerador es :
constructor TGenteEnumerator.Create(Lista: TGente);
begin
inherited Create;
fGente := Lista;
fPosicion := -1;
end;
function TGenteEnumerator.GetCurrent: TPersona;
begin
Result := fGente[fPosicion];
end;
function TGenteEnumerator.MoveNext: Boolean;
begin
if fPosicion < fGente.Count-1 then
begin
Inc(fPosicion);
Result := True;
end
else
Result := False;
end;
La implementación del metodo que devuelve el enumerador es:
function TGente.GetEnumerator: TGenteEnumerator;
begin
Result := TGenteEnumerator.Create(Self);
end;