TObjectList<> Get item error
Asked Answered
F

1

6

I'm trying to create TObjectList class in Delphi XE8, but i get errors when i try to get the value.

compiler error message: "[dcc32 Error] : can't access to private symbol {System.Generics.Collections}TList.GetItem"

Here is my code:

unit Unit2;
interface
uses
  Classes, System.SysUtils, System.Types, REST.Types, System.JSON, Data.Bind.Components,
  System.RegularExpressions, System.Variants,
  Generics.Collections;

  type
  TTruc = class
  public
    libelle : string;
    constructor Create(pLibelle : string);
  end;

  TListeDeTrucs = class(TObjectList<TTruc>)
  private
    function GetItem(Index: Integer): TTruc;
    procedure SetItem(Index: Integer; const Value: TTruc);
  public
    function Add(AObject: TTruc): Integer;
    procedure Insert(Index: Integer; AObject: TTruc);
    procedure Delete(Index: Integer);
    property Items[Index: Integer]: TTruc read GetItem write SetItem; default;
  end;

implementation

{ TTruc }

constructor TTruc.Create(pLibelle: string);
begin
  libelle := pLibelle;
end;

{ TListeDeTrucs }

function TListeDeTrucs.Add(AObject: TTruc): Integer;
begin
  result := inherited Add(AObject);
end;

procedure TListeDeTrucs.Insert(Index: Integer; AObject: TTruc);
begin
  inherited Insert(index, AObject);
end;

procedure TListeDeTrucs.Delete(Index: Integer);
begin
  inherited delete(index);
end;

function TListeDeTrucs.GetItem(Index: Integer): TTruc;
begin
  result := inherited GetItem(index);
end;

procedure TListeDeTrucs.SetItem(Index: Integer; const Value: TTruc);
begin
  inherited setItem(index, value);
end;
end.

the testing code is :

procedure TForm1.Button1Click(Sender: TObject);
var
  l : TListeDeTrucs;
  i : integer;
  Obj : TTruc;
begin
  l := TListeDeTrucs.Create(true);
  l.Add(TTruc.Create('one'));
  l.Add(TTruc.Create('two'));
  Obj := TTruc.Create('three');
  l.Add(Obj);
  for i := 0 to l.count - 1 do
  begin
    showMessage(l[i].libelle);
  end;
  L.Delete(0);
  l.extract(Obj);
  l.Free;
end;

How can i make it work ?

Frill answered 25/4, 2015 at 20:2 Comment(9)
Seems you are trying to use it in wrong way. You don't need to create new class to utilize functionality of TObjectList, check out example from docs and use in same way: docwiki.embarcadero.com/CodeExamples/XE8/en/…Hubey
I think you're misunderstanding how generics work. The entire point of using a generic TObjectList is to not have to create a new descendant for every type of object you want to store. You simply use MyTrucList: TObjectList<TTruc>; as the variable declaration, and then MyTrucList := TObjectList<TTruc>.Create; to create the list. You can then add a TTruc to the list with MyTrucList.Add(TTruc.Create); and fetch it back with MyTruc := MyTrucList[0];, with no need to typecast anything.Carp
in fact this is simple structure but TTruc class need to provide many vars and functions to be used including cascading instantiation of TListeDeTrucs (TListeDeTrucs use TTruc as items, but each TTruc items can instanciate another TListeDeTrucs ...) i just wrote here the code that make the problem not the whole projectFrill
The project is cascading Assoc Array (same than php know how to do it so well: $myarray['keylevel1']['keylevel2']['keylevel3'] = 'my value';)Frill
@Ken Fabien has cut the code down to an MCVE. The real code has complexity that we can't see.Rayford
None of that requires you to create a TObjectList descendant. The objects in TObjectList<T> can be whatever type of object you want, and they keep the full properties and functionality of the object itself. Those objects can have "many vars and functions" and still be in a plain TObjectList<T>, and each T in TObjectList<T> can contain anything (including another TObjectList<T>).Carp
I understand @Ken then give me a solution please. i want that the user can do something like : Myarray['KeyLevel1']['Keylevel2'].asString if i don't declare the TTruc how can i adress in the AsString function with the proper TTruc value ? because its included in the list. if i do the way you asking me to do, then i need to create a cursor inside the ObjectList... that will give wrong result if recursive call like this : Myarray['KeyLevel1'][Myarray['Key2'].asInteger].asString so give me solution if you have. i only find this way to do it properly. If a simple way exists, i buy it !Frill
My comments were based on your code posted (as well as your statement i'm newbie in TObjectList,), which led me to believe you were just making a mistake. You keep adding additional requirements (which are not clear yet), and "give me a solution to my class design problem which I did not ask about" certainly isn't the question you asked here, or in any way related to the code you posted above. If I answer that question here, it would be wrong, because that's not the question you asked. Based on what you've stated in comments, I can still see a way to do it without a TObjectList descendant.Carp
Thank you @Ken White, so you advise me to make a new post ? to find a better structure ? maybe when it's done i will post the full code for comment / share / adjustments ? does stackoverflow authorize to do things like this ?Frill
R
9

Well, GetItem, and indeed SetItem are private. Your code cannot see them. Private members can be seen only in the unit in which they are declared. You need to use members that are at least protected.

This compiles:

function TListeDeTrucs.GetItem(Index: Integer): TTruc;
begin
  Result := inherited Items[Index];
end;

procedure TListeDeTrucs.SetItem(Index: Integer; const Value: TTruc);
begin
  inherited Items[Index] := Value;
end;

In this case your class is a little pointless because none of the methods in your class vary behaviour from the base class. But peut-être your real class does more.

Rayford answered 25/4, 2015 at 20:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.