Search code examples
objectoopdelphiiterationdelphi-10.4-sydney

Delphi objects: shortcut for TObjectList iteration


I'm starting to learn and actively use OOP in my projects. I've found that constructions like LDevices.Devices[i] look very cumbersome and make code hard to read.

So there's my question: is there any way to be able to make a shortcut for a field to access it like LDevices[i], not LDevices.Devices[i]? Devices is TObjectList<TDevice>.

Structure of my object, for reference:

TDeviceStorage = class (TObject)
    private
      DevicesByID: TDictionary<Integer,TDevice>;
    public
      Devices: TObjectList<TDevice>;
      Constructor Create;
      Destructor Destroy; override;
      procedure AddDevice(aID: Integer; aName, aShortName: String; aSubtype, aLocation: Integer; aSteamID: String);
      procedure Clear();
      function Count(): Integer;
      function DeviceByID(aID: Integer): TDevice;
      function DeviceIndex(aID: Integer): Integer;
  end;

Solution

  • Yes, this is exactly what the default directive on an array property is used for:

    TDeviceStorage = class(TObject)
    private
      FDevicesByID: TDictionary<Integer, TDevice>;
      FDevices: TObjectList<TDevice>;
      function GetDeviceCount: Integer;
      function GetDevice(Index: Integer): TDevice;
      procedure SetDevice(Index: Integer; const Value: TDevice);
    public
      constructor Create;
      destructor Destroy; override;
      procedure AddDevice(AID: Integer; const AName, AShortName: string;
        ASubtype, ALocation: Integer; const ASteamID: string);
      procedure Clear;
      function DeviceByID(AID: Integer): TDevice;
      function DeviceIndex(AID: Integer): Integer;
      property Devices[Index: Integer]: TDevice read GetDevice write SetDevice; default;
      property DeviceCount: Integer read GetDeviceCount;
    end;
    

    with

    function TDeviceStorage.GetDevice(Index: Integer): TDevice;
    begin
      Result := FDevices[Index];
    end;
    
    function TDeviceStorage.GetDeviceCount: Integer;
    begin
      Result := FDevices.Count;
    end;
    
    procedure TDeviceStorage.SetDevice(Index: Integer; const Value: TDevice);
    begin
      FDevices[Index] := Value;
    end;
    

    Now, if DS: TDeviceStorage, you can write DS[i] to access the ith device in FDevices.