Delphi之For In

Java和C#里面的For In用起来真爽,我们Delphin也不用眼红了,从D2005起,Delphi里面也有这个功能了.


首先我们要知道哪些类型可以用For In吧,下面就是:

  • 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;         结构体


我们来看例子:

01 type
02 THuangJacky = (hjA,hjB,hjC,hjD);
03 TJackyHuang = record
04     a,b,c:Integer;
05 end;
06 const
07     stringExpr='HuangJacky';
08     arrayExpr:array[0..5] of Integer= (1,2,3,4,5,6);
09     setExpr:set of THuangJacky = [hjA,hjB,hjD];
10 procedure TForm1.FormCreate(Sender: TObject);
11 var
12     I:Integer;
13     C:Char;
14     D:THuangJacky;
15     F:TComponent;
16 begin
17 for c in stringExpr do
18     ShowMessage(C);
19 for i in arrayExpr do
20     ShowMessage(IntToStr(i));
21 for d in setExpr do
22     ShowMessage(IntToStr(Ord(d)));
23 for F in Self do
24     ShowMessage(f.Name);
25 end;


是不是很爽呀?哈哈,Delphi也与时俱进呀.

之前写了类助手文章中,老赵问是不是扩展方法,因为对C#没有了解到这么多,所以不知道.
那么我们在Java中要For In必须实现Iterator吧.
那么Delphi的会不会也要呢?
是的,如果我们要自己的类支持For In的话,就必须满足下面的条件:
1 必须有个公共方法GetEnumerator(),这个方法返回值是一个类,接口或者记录体.
2 上面返回的类,接口或者记录体中又必须有公共方法MoveNext(),这个方法的返回值是Boolean.
3 1中返回的类,接口或者记录体中必须有一个只读的属性Current,类型要和集合中的元素一样.

说了这么多,看个例子:

01 type
02   TMyIntArray = array of Integer;
03   
04   TMyEnumerator = class
05     Values: TMyIntArray;
06     Index:  Integer;
07   public
08     constructor Create;
09     function GetCurrent: Integer;
10     function MoveNext:   Boolean;
11     property Current:    Integer read GetCurrent;
12   end;
13   
14   TMyContainer  = class
15   public
16    function GetEnumerator: TMyEnumerator;
17   end;
18   
19 constructor TMyEnumerator.Create;
20 begin
21   inherited Create;
22   Values := TMyIntArray.Create(100, 200, 300);
23   Index := -1;
24 end;
25   
26 function TMyEnumerator.MoveNext: Boolean;
27 begin
28   if Index < High(Values) then
29     begin
30       Inc(Index);
31       Result := True;
32     end
33   else
34     Result := False;
35 end;
36   
37 function TMyEnumerator.GetCurrent: Integer;
38 begin
39   Result := Values[Index];
40 end;
41   
42 function TMyContainer.GetEnumerator: TMyEnumerator;
43 begin
44   Result := TMyEnumerator.Create;
45 end;
46   
47 var
48   MyContainer: TMyContainer;
49   I: Integer;
50   
51   Counter: Integer;
52   
53 begin
54   MyContainer := TMyContainer.Create;
55   
56   Counter := 0;
57   for I in MyContainer do
58     Inc(Counter, I);
59   
60   WriteLn('Counter = ', Counter);
61 end.
posted @ 2010-05-22 15:31  静.思  阅读(3752)  评论(0编辑  收藏  举报