Home > Blockchain >  How to pass class reference (metaclass) as a parameter in procedure?
How to pass class reference (metaclass) as a parameter in procedure?

Time:10-14

There are two objects: TFoo, TFoo2.

There is also a class reference : TFooClass = class of TFoo;

Both are descendants from TPersistent.

They have their own constructors:

type
  TFoo = class(TPersistent)
  private
    FC:Char;
  public
    constructor Create; virtual;
  published
    property C:Char read FC write FC;
  end;
    
  TFoo2 = class(TFoo)
  public
    constructor Create; override;
  end;

  TFooClass = class of TFoo;

...

constructor TFoo.Create;
begin
  inherited Create;
  C :=' 1';
end;
    
constructor TFoo2.Create;
begin
  inherited Create;
  C := '2';
end;

I want to create a TFoo2 object from a string, which is actually its class name : 'TFoo2'

Here is the procedure, which works fine:

procedure Conjure(AClassName:string);
var
  PClass : TPersistentClass;
  p :TPersistent;
begin
  PClass := TPersistentClass(FindClass(AClassName))
  p := TFooClass(PClass).Create;  // <-- here is called appropriate constructor  
end;

Now, I want to have similar objects like: TBobodo, TBobodo2.

And a class reference of course : TBobodoClass = class of TBobodo;

And so on...

Now, how can I pass a class reference as a parameter into a procedure, in order to secure the right constructor is called?

procedure Conjure(AClassName:string; ACLSREF: ???? ); // <-- something like that 
var
  PClass : TPersistentClass;
  p :TPersistent;
begin
  PClass := TPersistentClass(FindClass(AClassName))
  p := ACLSREF(PClass).Create;  // <-- something like that  
end;

Is it possible?

CodePudding user response:

There is no way to do what you want in Delphi 7. The metaclass reference has to be explicit at compile-time at the call site, not handled at runtime.

In Delphi 2009 and later, you may 1 be able to do something with Generics, eg:

1: I have not tried this myself yet.

type
  TConjureHelper = class
  public
    class procedure Conjure<TClassType>(const AClassName: string);
  end;

class procedure TConjureHelper.Conjure<TClassType>(const AClassName: string);
var
  PClass : TPersistentClass;
  p : TPersistent;
begin
  PClass := TPersistentClass(FindClass(AClassName));
  p := TClassType(PClass).Create;
  ...
end;

...

TConjureHelper.Conjure<TFooClass>('TFoo2');
TConjureHelper.Conjure<TBobodoClass>('TBobodo2');
...

But Delphi 7 certainly does not support Generics.

  • Related