我已經定義了一個從TDictionary派生的集合,並且需要定義一個應用附加過濾器的自定義枚舉器。如何爲從TDictionary派生的類創建自定義枚舉器?
我堅持,因爲我無法訪問TDictionary FItems陣列(它是私有的),所以我不能確定MoveNext方法
你會如何繼續重新定義從派生的類過濾枚舉TDictionary?
這裏有一個簡單的代碼來說明我想做的事:
TMyItem = class(TObject)
public
IsHidden:Boolean; // The enumerator should not return hidden items
end;
TMyCollection<T:TMyItem> = class(TDictionary<integer,T>)
public
function GetEnumerator:TMyEnumerator<T>; // A value filtered enumerator
type
TMyEnumerator = class(TEnumerator<T>)
private
FDictionary: TMyCollection<integer,T>;
FIndex: Integer;
function GetCurrent: T;
protected
function DoGetCurrent: T; override;
function DoMoveNext: Boolean; override;
public
constructor Create(ADictionary: TMyCollection<integer,T>);
property Current: T read GetCurrent;
function MoveNext: Boolean;
end;
end;
function TMyCollection<T>.TMyEnumerator.MoveNext: Boolean;
begin
// In below code, FIndex is not accessible, so I can't move forward until my filter applies
while FIndex < Length(FDictionary.FItems) - 1 do
begin
Inc(FIndex);
if (FDictionary.FItems[FIndex].HashCode <> 0)
and not(FDictionary.FItems[FIndex].IsHidden) then // my filter
Exit(True);
end;
Result := False;
end;
感謝這個完整的示例,我現在更好地理解如何使用枚舉器。我還發現,包裝枚舉器有一個巨大的性能損失(在我的示例應用程序中,對象查詢需要常規TDictionary枚舉器2.2ms,包裝枚舉器3.3ms(+ 50%!),而不應用任何過濾器)。 – user315561 2011-05-19 07:24:21
@ user315561,什麼需要2.2ms?在現代CPU上2.2毫秒是一個可怕的長時間,你可能錯過了一些東西;並且這使得包裝的枚舉器的3.3ms結果同樣是錯誤的。 – 2011-05-19 07:45:16
我同意我的數字在背景下提供,並不相關。用例是對75000個對象集合的查詢,按順序瀏覽一個簡單的相等過濾器,並將850個匹配對象添加到新的結果集合中。我想在這裏強調的是枚舉器封裝的成本懲罰(在相同的用例中),這是相關並且很好知道的。 – user315561 2011-05-19 10:35:44