Search Results

Search found 2 results on 1 pages for 'afrazier'.

Page 1/1 | 1 

  • Delphi: Using Enumerators to filter TList<T: class> by class type?

    - by afrazier
    Okay, this might be confusing. What I'm trying to do is use an enumerator to only return certain items in a generic list based on class type. Given the following hierarchy: type TShapeClass = class of TShape; TShape = class(TObject) private FId: Integer; public function ToString: string; override; property Id: Integer read FId write FId; end; TCircle = class(TShape) private FDiameter: Integer; public property Diameter: Integer read FDiameter write FDiameter; end; TSquare = class(TShape) private FSideLength: Integer; public property SideLength: Integer read FSideLength write FSideLength; end; TShapeList = class(TObjectList<TShape>) end; How can I extend TShapeList such that I can do something similar to the following: procedure Foo; var ShapeList: TShapeList; Shape: TShape; Circle: TCircle; Square: TSquare; begin // Create ShapeList and fill with TCircles and TSquares for Circle in ShapeList<TCircle> do begin // do something with each TCircle in ShapeList end; for Square in ShapeList<TSquare> do begin // do something with each TSquare in ShapeList end; for Shape in ShapeList<TShape> do begin // do something with every object in TShapeList end; end; I've tried extending TShapeList using an adapted version of Primoz Gabrijelcic's bit on Parameterized Enumerators using a factory record as follows: type TShapeList = class(TObjectList<TShape>) public type TShapeFilterEnumerator<T: TShape> = record private FShapeList: TShapeList; FClass: TShapeClass; FIndex: Integer; function GetCurrent: T; public constructor Create(ShapeList: TShapeList); function MoveNext: Boolean; property Current: T read GetCurrent; end; TShapeFilterFactory<T: TShape> = record private FShapeList: TShapeList; public constructor Create(ShapeList: TShapeList); function GetEnumerator: TShapeFilterEnumerator<T>; end; function FilteredEnumerator<T: TShape>: TShapeFilterFactory<T>; end; Then I modified Foo to be: procedure Foo; var ShapeList: TShapeList; Shape: TShape; Circle: TCircle; Square: TSquare; begin // Create ShapeList and fill with TCircles and TSquares for Circle in ShapeList.FilteredEnumerator<TCircle> do begin // do something with each TCircle in ShapeList end; for Square in ShapeList.FilteredEnumerator<TSquare> do begin // do something with each TSquare in ShapeList end; for Shape in ShapeList.FilteredEnumerator<TShape> do begin // do something with every object in TShapeList end; end; However, Delphi 2010 is throwing an error when I try to compile Foo about Incompatible types: TCircle and TShape. If I comment out the TCircle loop, then I get a similar error about TSquare. If I comment the TSquare loop out as well, the code compiles and works. Well, it works in the sense that it enumerates every object since they all descend from TShape. The strange thing is that the line number that the compiler indicates is 2 lines beyond the end of my file. In my demo project, it indicated line 177, but there's only 175 lines. Is there any way to make this work? I'd like to be able to assign to Circle directly without going through any typecasts or checking in my for loop itself.

    Read the article

  • Do I have to allocate and free records when using TList<T> in Delphi?

    - by afrazier
    The question more or less says it all. Given the following record structure: type TPerson = record Name: string; Age: Integer; end; PPerson = ^TPerson; TPersonList = TList<TPerson>; Is the following code valid? procedure ReadPeople(DataSet: TDataSet; PersonList: TPersonList); begin PersonList.Count := DataSet.RecordCount; if DataSet.RecordCount = 0 then Exit; DataSet.First; while not DataSet.Eof do begin PersonList[DataSet.RecNo].Name := DataSet.FieldByName('Name').AsString; PersonList[DataSet.RecNo].Age := DataSet.FieldByName('Age').AsInteger; DataSet.Next; end; end; Do I have to use GetMem/FreeMem to allocate and free records an instance of TPersonList, or am I free to directly access the TPersonList entries directly? My gut says that the code should be valid, though I'm not sure if there's any wrinkles related to record initialization or finalization.

    Read the article

1