我正在尝试为私有静态数组公开 TEnumerator 中的构建。
Delphi 本身允许直接枚举静态数组(见下文),所以我怀疑 Delphi 在后台为静态数组创建了一个枚举器,我希望我能够在 GetEnumerator 方法中创建和公开相同的枚举器。
(我使用的是德尔福 XE2)。
program Project6;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Generics.Collections;
type
TMyEnum = (meA, meB);
TMyClass = class
private
FItems: array[TMyEnum] of Integer;
protected
public
function GetEnumerator: TEnumerator<Integer>;
end;
{ TMyClass }
function TMyClass.GetEnumerator: TEnumerator<Integer>;
begin
// What is the simplies way of creating this enumerator?
end;
var
myObj: TMyClass;
i: Integer;
begin
myObj := TMyClass.Create;
try
// This works but only in the same unit
for i in myObj.FItems do
WriteLn(i);
for i in myObj do
WriteLn(i);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
ReadLn;
end.
请注意,我可以编写如下所示的自定义模拟器。但我试图避免这种情况并公开内置的。
TStaticArrayEnumerator<T> = class(TEnumerator<T>)
private
FCurrent: Pointer;
FElementAfterLast: Pointer;
protected
function DoGetCurrent: T; override;
function DoMoveNext: Boolean; override;
public
constructor Create(aArray: Pointer; aCount: Integer);
end;
{ TStaticArrayEnumerator<T> }
constructor TStaticArrayEnumerator<T>.Create(aArray: Pointer; aCount: Integer);
begin
// need to point Current before the first element (see comment in DoMoveNext)
FCurrent := Pointer(NativeInt(aArray) - SizeOf(T));
FElementSize := aElementSize;
FElementAfterLast := Pointer(NativeInt(aArray) + aCount * SizeOf(T))
end;
function TStaticArrayEnumerator<T>.DoGetCurrent: T;
begin
Result := T(FCurrent^);
end;
function TStaticArrayEnumerator<T>.DoMoveNext: Boolean;
begin
// This method gets called before DoGetCurrent gets called the first time
FCurrent := Pointer(NativeInt(FCurrent) + SizeOf(T));
Result := not (FCurrent = FElementAfterLast);
end;