PDA

Visualizza la versione completa : [Delphi] Accedere ai metodi private/protected


Jey
16-01-2013, 17:10
Ho un problema. :dhò:
Il mio obiettivo è eseguire dei metodi presenti in una classe.
Mi spiego meglio.

Supponiamo di avere una form con solamente una TEdit e un TButton.
Nella TEdit inserisco il nome di un metodo presente in una qualsiasi classe ( per esempio il metodo GetControlsAlignment del TPanel ) e, alla pressione del bottone, eseguo il metodo.

Per eseguire il metodo uso l'Rtti in questo modo:


function TMyLibClass.RttiMethodInvokeEx( const lsMethodName:string; loRttiType : TRttiType; loInstance: TObject; const laoArgs: array of TValue ): TValue;
var
lbFound : Boolean;
loMethod : TRttiMethod;
i : Integer;
laoParams : TArray<TRttiParameter>;
begin
Result := nil;
try
loMethod := nil;
lbFound := false;
for loMethod in loRttiType.GetMethods do
begin
if SameText( UpperCase( loMethod.Name ), UpperCase( lsMethodName ) ) then
begin
laoParams := loMethod.GetParameters;
if Length( laoArgs ) = Length( laoParams ) then
begin
lbFound := true;
for i := 0 to Length( laoParams ) - 1 do
begin
if laoParams[i].ParamType.Handle <> laoArgs[i].TypeInfo then
begin
lbFound := false;
break;
end;
end;
end;
if lbFound then
begin
break;
end;
end;
end;
if ( loMethod <> nil ) and
( lbFound ) then
begin
Result := loMethod.Invoke( loInstance, laoArgs );
end else
begin
raise Exception.CreateFmt( 'method %s not found', [lsMethodName] );
end;
except
end;
end;


Il tutto funziona egregiamete, fino a quando non provo ad eseguire un metodo dichiarato private/protected.
Se non ho capito male il problema è che con l'Rtti riesco a vedere solamente i metodi pubblici. Esatto? :confused:
C'è un modo per accedere anche a quelli private/protected?

Scara95
16-01-2013, 18:56
Private e protected fanno esattamente il loro lavoro: non permetterti di toccare la rappresentazione interna della classe. Non c'è alcun motivo di andare a toccare metodi dichiarati in tal modo: se ci fosse sarebbero stati dichiarati public...
L'unico modo per accedervi è dall'interno della classe stessa...

Hard*RTOS
16-01-2013, 19:58
Originariamente inviato da Jey
C'è un modo per accedere anche a quelli private/protected?

Come già suggerito, ovviamente no: se c'è necessità di accesso a tali metodi o variabili, è necessario impostarle come Public; se l'accesso fosse consentito, non avrebbe senso il tipo Private o Protected, riservato a quei metodi/variabili che non devono essere 'visibili' da classi estranee.

Jey
16-01-2013, 20:24
Sono d'accordo su ciò che dichiaro private, ma su qualcosa dichiarato protected non è vero che è visibile solo all'interno della classe stessa...

Vi faccio un esempio col TButton:



type
TMyButton = class(TButton);

TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
end;

var
Form1: TForm1;

implementation


procedure TForm1.FormCreate(Sender: TObject);
var
c : TMyButton;
begin
c := TMyButton.Create( Self );
end;


Così facendo, anche all'interno della classe TForm1, vedo i metodi protected dell'oggetto TMyButton...

Quindi, riassumendo, ok per i metodi private ( immaginavo non si potesse per questi ), ma esiste un modo per vedere i metodi protected senza dover fare questo giro?

Scara95
16-01-2013, 20:48
Protected e private sono la stessa cosa finché non entra in campo l'ereditarietà...
Ti suggerisco di rivedere le basi dell'OOP...

Jey
16-01-2013, 21:07
Appunto... Conosco il funzionamento di private e protected, però, visto che è da poco che uso i metodi Rtti e non conosco bene il loro funzionamento, mi chiedevo se fosse possibile vedere anche metodi private/protected tramite questi, visto che per quanto riguarda le variabili ho visibilità sia su quelle private che protected se non erro.

Se non fosse possibile non mi sorprenderebbe, anzi. Chiedevo solo una conferma :D

Grazie mille per le risposte :)

Hard*RTOS
16-01-2013, 21:17
Originariamente inviato da Jey
Grazie mille per le risposte :)

Prego, figurati

Ciao :)

franzauker2.0
16-01-2013, 22:21
Bhè se non ti spaventano approcci diciamo così eterodossi puoi banalmente dichiarare un tipo derivato dalla classe che vuoi, nello stesso file PAS, et voilà puoi accedere ai protected

type tqualcosa = class(tquellocuivuoiaccedere);

variabile: tquellocuivuoiaccedere;
...

tqualcosa(variabile).ENTRIAMODENTRO:=...

Jey
16-01-2013, 22:33
Si facendo così ottengo l'accesso ai metodi protected :)
Però non mi risolve il problema :(

Quello che stavo cercando di fare era una specie di interprete capace di eseguire codice a run time.
Io ho il mio applicativo con ad esempio una TMemo, lì ci scrivo il codice e lui a run time esegue il tutto.

Col metodo che ho scritto sopra riesco a richiamare le varie procedure pubbliche degli oggetti ( es. se scrivessi form1.button1.Refresh funziona tutto tranquillamente ).

Mi sarebbe stato comodo riuscire a richiamare anche i metodi protected perchè ho degli oggetti miei da gestire così e non volevo modificarli e rendere pubblici i metodi di mio interesse. :dhò:

Ma se non si può fare pazienza :)

franzauker2.0
16-01-2013, 23:01
???
Io ho il mio applicativo con ad esempio una TMemo, lì ci scrivo il codice e lui a run time esegue il tutto.Cosa vorrebbe dire questo ???

Loading