delphi - operadores - sobrecarga de metodos en java netbeans
La función TRttiMethod.Invoke no funciona en métodos sobrecargados? (1)
No hay nada de malo con el método TRttiMethod.Invoke
, su problema se encuentra en GetMethod
. Esta función llama internamente a TRttiType.GetMethods
y recupera un puntero al primer método que coincide con el nombre pasado como parámetro. Por lo tanto, cuando está ejecutando este código t.GetMethod(''Create'')
siempre obtendrá un puntero al mismo método.
Para ejecutar una versión sobrecargada del constructor u otro método, debe resolver la dirección del método a ejecutar en base a los parámetros, y luego llamar a la función TRttiMethod.Invoke
.
Verifique esta función de muestra.
function RttiMethodInvokeEx(const MethodName:string; RttiType : TRttiType; Instance: TValue; const Args: array of TValue): TValue;
var
Found : Boolean;
LMethod : TRttiMethod;
LIndex : Integer;
LParams : TArray<TRttiParameter>;
begin
Result:=nil;
LMethod:=nil;
Found:=False;
for LMethod in RttiType.GetMethods do
if SameText(LMethod.Name, MethodName) then
begin
LParams:=LMethod.GetParameters;
if Length(Args)=Length(LParams) then
begin
Found:=True;
for LIndex:=0 to Length(LParams)-1 do
if LParams[LIndex].ParamType.Handle<>Args[LIndex].TypeInfo then
begin
Found:=False;
Break;
end;
end;
if Found then Break;
end;
if (LMethod<>nil) and Found then
Result:=LMethod.Invoke(Instance, Args)
else
raise Exception.CreateFmt(''method %s not found'',[MethodName]);
end;
Ahora puede llamar a los constructores o métodos de su clase de una de estas maneras
r := RttiMethodInvokeEx(''Create'', t, t.MetaclassType, [444]);
r := RttiMethodInvokeEx(''Create'', t, t.MetaclassType, [''hello from constructor string'']);
r := RttiMethodInvokeEx(''Create'', t, t.MetaclassType, []);
RttiMethodInvokeEx(''Bar'', t, r.AsObject , [''this is a string'']);
RttiMethodInvokeEx(''Bar'', t, r.AsObject , [9999]);
Estoy creando una instancia de una clase usando la función TRttiMethod.Invoke , pero cuando el constructor o un método está sobrecargado, el rtti no llama al método apropiado.
Escribí una aplicación de muestra para resolver mi problema.
program ProjectFoo;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Rtti,
System.SysUtils;
type
TFoo=class
public
constructor Create(Value : Integer);overload;
constructor Create(const Value : string);overload;
function Bar(value : integer) : Integer; overload;
function Bar(const value : string) : string; overload;
end;
{ TFoo }
constructor TFoo.Create(Value: Integer);
begin
Writeln(Value);
end;
function TFoo.Bar(value: integer): Integer;
begin
Writeln(Value);
Result:=value;
end;
function TFoo.Bar(const value: string): string;
begin
Writeln(Value);
Result:=value;
end;
constructor TFoo.Create(const Value: string);
begin
Writeln(Value);
end;
var
c : TRttiContext;
t : TRttiInstanceType;
r : TValue;
begin
try
c := TRttiContext.Create;
t := (c.GetType(TFoo) as TRttiInstanceType);
r := t.GetMethod(''Create'').Invoke(t.MetaclassType,[444]);//this works
//r := t.GetMethod(''Create'').Invoke(t.MetaclassType,[''hello from constructor string'']);//this fails : EInvalidCast: Invalid class typecast
t.GetMethod(''Bar'').Invoke(r,[1]);// this works
//t.GetMethod(''Bar'').Invoke(r,[''Hello from bar'']); //this fails : EInvalidCast: Invalid class typecast
except
on E: Exception do
Writeln(E.ClassName, '': '', E.Message);
end;
readln;
end.
Este es un error RTTI? ¿O existe otra forma de llamar a los métodos sobrecargados de una clase usando RTTI?