2010-03-23 11 views
8

Tengo dos preguntas (de los cuales al menos uno es con respecto a RTTI en D2010 y la creación de instancias dinámico)Delphi 2010: ¿qué pasó con TRTTIConstructor?

  1. estaba leyendo lo que parece ser las láminas para una conference talk por Barry Kelly, y conocer en p. 13 algo que parecía realmente interesante: TRTTIConstructor.Invoke. En un punto de viñeta adyacente, se encuentra "Crear instancias dinámicamente sin necesidad de constructores virtuales y metaclases". ¡Esto parece una gran característica (y exactamente lo que necesito, por cierto)! Sin embargo, cuando miro en los documentos D2010 (ms-help: //embarcadero.rs2010/vcl/Rtti.html), no puedo encontrarlo. ¿Fue revocado?
  2. ¿Cuál es la forma mínima de crear una instancia de una clase, siempre que el nombre de clase esté almacenado en una cadena?

Respuesta

10

Creo que la funcionalidad ha sido absorbida por TRttiMethod. Tiene las propiedades IsConstructor, IsDestructor e IsClassMethod para que pueda usarse tanto para métodos "especiales" como normales.

En cuanto a la pregunta 2, intentar algo como esto:

function GetConstructor(val: TRttiInstanceType): TRttiMethod; 
var 
    method: TRttiMethod; 
begin 
    for method in val.GetMethods('Create') do 
    begin 
     if (method.IsConstructor) and (length(method.GetParameters) = 0) then 
     exit(method); 
    end; 
    raise EInsufficientRTTI.CreateFmt('No simple constructor available for class %s ', 
            [val.MetaclassType.ClassName]); 
end; 

Esto encuentra el mayor constructor llamado Create que no toma ningún parámetro. Puede modificarlo para buscar otros constructores con otras firmas, si sabe lo que está buscando. Entonces simplemente llame al Invoke en el resultado.

+1

Gracias de nuevo albañil! Usted (y las otras personas aquí en SO) prácticamente cierran la brecha de documentación. Muchas gracias. + 1 – conciliator

+1

Me alegra ayudar. Estuve en esa charla, y D2010 todavía estaba en beta en ese momento. Parece que algunas cosas han cambiado desde entonces hasta la versión final. Me pregunto por qué se eliminó HasAttribute. Eso sería muy útil! –

2

Aunque puede llamar a .GetMethod() para obtener el constructor, también puede hacer lo siguiente para construir instancias de objetos sin parámetros para el constructor.

function CreateInstance(aType : TRttiType) : TObject; 
begin 
    // Option #1 
    result := aType.AsInstance.MetaclassType.Create; 
    // Option #2 
    result := aType.GetMethod('Create').Invoke(aType.AsInstance.MetaclassType,[]); 
end; 

Si conoce el tipo de base, puede escribir el tipo de conversión para pasar los parámetros si lo desea. He aquí un ejemplo de cómo crear un componente

result := TComponentClass(aType.AsInstance.MetaClassType).Create(OwnerValue);

+0

¡Gracias Robert! Para mi proyecto actual, conozco el tipo base de antemano, por lo que la última línea en su respuesta sería exactamente lo que ordenó el médico. (+1) Sin embargo, obtengo una infracción de acceso cuando ejecuto Button: = TButton (RType.ClassType) .Create (self); donde Button: TButton y self es el formulario de propietario, y RType: TRTTIType creado por RType: = RContext.FindType ('StdCtrls.TButton'); (y el contexto ya está creado). ¿Qué estoy haciendo mal? – conciliator

+0

Pruebe esto: Botón: = TComponentClass (RType.AsInstance.MetaclassType) .Create (Self) como TButton; –

+0

Gracias, VilleK. Por desgracia, todavía tengo una infracción de acceso. Supongo que debería hacer una publicación por separado con respecto a esto. – conciliator