La solución de Alexander es buena pero no es suficiente en ciertas situaciones. Supongamos que desea configurar una clase TClassFactory donde las referencias de TClass puedan almacenarse durante el tiempo de ejecución y un número arbitrario de instancias recuperadas posteriormente.
Tal clase de fábrica nunca sabría nada sobre los tipos reales de las clases que posee y, por lo tanto, no puede convertirlas en sus metacategorías. Para invocar a los constructores correctos en tales casos, el siguiente enfoque funcionará.
En primer lugar, necesitamos una clase de demostración simple (no importa los campos públicos, es sólo para fines de demostración).
interface
uses
RTTI;
type
THuman = class(TObject)
public
Name: string;
Age: Integer;
constructor Create(); virtual;
end;
implementation
constructor THuman.Create();
begin
Name:= 'John Doe';
Age:= -1;
end;
Ahora instanciamos un objeto de tipo THuman puramente por RTTI y con la llamada de constructor correcta.
procedure CreateInstance();
var
someclass: TClass;
c: TRttiContext;
t: TRttiType;
v: TValue;
human1, human2, human3: THuman;
begin
someclass:= THuman;
// Invoke RTTI
c:= TRttiContext.Create;
t:= c.GetType(someclass);
// Variant 1a - instantiates a THuman object but calls constructor of TObject
human1:= t.AsInstance.MetaclassType.Create;
// Variant 1b - same result as 1a
human2:= THuman(someclass.Create);
// Variant 2 - works fine
v:= t.GetMethod('Create').Invoke(t.AsInstance.MetaclassType,[]);
human3:= THuman(v.AsObject);
// free RttiContext record (see text below) and the rest
c.Free;
human1.Destroy;
human2.Destroy;
human3.Destroy;
end;
Usted encontrará que los objetos "human1" y "human2" se han inicializado a cero, es decir, Name = '' y la Edad = 0, lo cual no es lo que queremos. El objeto human3 en cambio contiene los valores predeterminados proporcionados en el constructor de THuman.
Tenga en cuenta, sin embargo, que este método requiere que sus clases tengan métodos de construcción sin parámetros. Todo lo anterior no fue concebido por mí, sino que se explicó brillantemente y con mucho más detalle (por ejemplo, la parte c.Free) en Rob Love's Tech Corner.
Ok, si entiendo correctamente esto significa que si quiero construir una fábrica de objetos genéricos con Delphi, necesito asignar "clase de TMyClass" a una variable, pero esto no parece posible. – mjn
Si desea construir un objeto de cierto tipo, entonces necesita tener información de tipo de clase. Si no tiene información de clase, no puede construir un objeto de este tipo. Bastante obvio;) – Alex