0

Hello I have a question is possible I do a loop for create subclass in Delphi? I saw some about RTTI but I can't found how create a class in property in run time

exemple

thank you

Type
  TclassX = class
  private
  public
     X1 : integer;
     X2 : String;
end;

Type

  TRecord = class
     ID : TClassX;
     NAME : TClassX;
  private
  public
     contructor Create();
     property ID : TClassX read FY1 write SetY1;
     property NAME : TClassX read FY2 write SetY2;
end;

implementation

constructor TRecord.Create;
begin
   ///HERE I WHANT MAKE A LOOP AND DON'T MAKE ONE BY ONE
   // property[0] := ID;
   // property[1] := NAME;
   // FOR I:= 0 TO 1 DO BEGIN
   // ***PROPERTY[i] := TClassX.Create; ---*** not correct just exemple
   // END; 

   ID := TClassY.Create;  
   NAME := TClassY.Create;  
end;

1 Answers1

1

I would store the class references in an array. And then for syntactical ease, use an indexed property:

type
  TMyClass = class
  private
    FY: array [1..2] of TClassX;
    function GetY(Index: Integer): TClassX;
    procedure SetY(Index: Integer; const Value: TClassX);
  public
    constructor Create;
    property Y1: TClassX index 1 read GetY write SetY;
    property Y2: TClassX index 2 read GetY write SetY;
  end;

function TMyClass.GetY(Index: Integer): TClassX;
begin
  Result := FY[Index];
end;

procedure TMyClass.SetY(Index: Integer; const Value: TClassX);
begin
  FY[Index] := Value;
end;

Then you can simply loop over FY to instantiate the objects.

constructor TMyClass.Create;
var
  i: Integer;
begin
  inherited;
  for i := low(FY) to high(FY) do begin
    FY[i] := TClassY.Create;
  end;
end;

Having said all that, is all of this scaffolding really necessary. Would it not just be easier to use an array property?

type
  TMyClass = class
  private
    FY: array [1..2] of TClassX;
    function GetY(Index: Integer): TClassX;
    procedure SetY(Index: Integer; const Value: TClassX);
  public
    constructor Create;
    property Y[Index: Integer]: TClassX read GetY write SetY;
  end;

Then, instead of writing Y1 you write Y[1]. Using array properties gives you so much more flexibility because you can index them with variables and so decide at runtime rather than compile time which object you are referring to.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Tks David this is perfect for my case! – Francisco RHP Mar 28 '13 at 12:48
  • but! If I need some exclusive for only a field! for exemplo in index property Y1 need change same value before read I need use a if or case ? – Francisco RHP Mar 28 '13 at 13:13
  • I don't really understand that comment. I think I answered the question that you asked. – David Heffernan Mar 28 '13 at 13:21
  • if I need stupid exemplo Result := FY[Index] + 1; in only one filed – Francisco RHP Mar 28 '13 at 13:43
  • That code doesn't make much sense to me. You cannot use the + operator on an object. – David Heffernan Mar 28 '13 at 13:43
  • because this is a stupid code rs result := FY[index].X1 := FY[index].X1 + 1; in this case is only valid for X1 is only a exemplo for know what need do IF have same change – Francisco RHP Mar 28 '13 at 14:10
  • because I create a class for work with domain in Firebird the name is TDomain inside have ( Type ( string, int .. .), Size, botnull ... ) and I have another class the name TField where have ( name, value, TDomain ) and if TDomain is string have diferent function for this if is integer too if is datetime too! because this my answer about if I need put same 'case' or 'if' for send diferent result IF the field need same diferent or have another way for this! tks – Francisco RHP Mar 28 '13 at 14:33