IArray3: array[1..2] of TIntArray = ((11, 12, 13, 14, 15, 16, 17, 18, 19, 20),
(21, 22, 23, 24, 25, 26, 27, 28, 29, 30));
MultiDimTemp: TIntArray;
IDynArray: TGenericIntArray;
I: Integer;
begin
for I in IArray1 do
begin
// Do something with I...
end;
// Indexing begins at lower array bound of 1.
for I in IArray2 do
begin
// Do something with I...
end;
// Iterating a multi-dimensional array
for MultiDimTemp in IArray3 do // Indexing from 1..2
for I in MultiDimTemp do // Indexing from 0..9
begin
// Do something with I...
end;
// Iterating
over a dynamic array
IDynArray := IArray1;
for I in IDynArray do
begin
// Do something with I...
end;
The following code example demonstrates iteration over string expressions:
var
C: Char;
S1, S2: String;
Counter: Integer;
OS1, OS2: ShortString;
AC: AnsiChar;
begin
S1 := 'Now is the time for all good men to come to the aid of their country.';
S2 := '';
for C in S1 do
S2 := S2 + C;
if S1 = S2 then
WriteLn('SUCCESS #1');
else
WriteLn('FAIL #1');
OS1 := 'When in the course of human events it becomes necessary to dissolve...';
OS2 := '';
42
for AC in OS1 do
OS2 := OS2 + AC;
if OS1 = OS2 then
WriteLn('SUCCESS #2');
else
WriteLn('FAIL #2');
end.
The following code example demonstrates iteration over set expressions:
type
TMyThing = (one, two, three);
TMySet = set of TMyThing;
TCharSet = set of Char;
var
MySet: TMySet;
MyThing: TMyThing;
CharSet: TCharSet;
{$IF DEFINED(CLR)}
C: AnsiChar;
{$ELSE}
C: Char;
{$IFEND}
begin
MySet := [one, two, three];
for MyThing in MySet do
begin
// Do something with MyThing...
end;
CharSet := [#0..#255];
for C in CharSet do
begin
// Do something with C...
end;
end.
To use the for-in loop construct on a class, the class must implement a prescribed collection pattern. A type that
implements the collection pattern must have the following attributes:
The class 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 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.
43
If the enumerator type returned by
GetEnumerator()
implements the IDisposable interface, the compiler will call
the type's Dispose method when the loop terminates.
The following code demonstrates iterating over an enumerable container in Delphi.
type
TMyIntArray = array of Integer;
TMyEnumerator = class
Values: TMyIntArray;
Index: Integer;
public
constructor Create;
function GetCurrent: Integer;
function MoveNext:
Boolean;
property Current: Integer read GetCurrent;
end;
TMyContainer = class
public
function GetEnumerator: TMyEnumerator;
end;
constructor TMyEnumerator.Create;
begin
inherited Create;
Values := TMyIntArray.Create(100, 200, 300);
Index := -1;
end;
function TMyEnumerator.MoveNext: Boolean;
begin
if Index < High(Values) then
begin
Inc(Index);
Result := True;
end
else
Result := False;
end;
function TMyEnumerator.GetCurrent: Integer;
begin
Result := Values[Index];
end;
function TMyContainer.GetEnumerator: TMyThing;
begin
Result := TMyEnumerator.Create;
end;
var
MyContainer: TMyContainer;
I: Integer;
Counter: Integer;
begin
MyContainer := TMyContainer.Create;
44
Counter := 0;
for I in MyContainer do
Inc(Counter, I);
WriteLn('Counter = ', Counter);
end.
The following classes and their descendents support the for-in syntax:
TList
TCollection
TStrings
TInterfaceList
TComponent
TMenuItem
TCustomActionList
TFields
TListItems
TTreeNodes
TToolBar
Dostları ilə paylaş: