2012-02-23 21 views
28

Esta es una pregunta de seguimiento a: How to hide a protected procedure of an object?
(soy un poco difusa en todo el concepto ayudante de clase)¿Cómo uso los ayudantes de clase para acceder a miembros privados estrictos de una clase?

Supongamos que tengo una clase como:

type 
TShy = class(TObject) 
strict private 
    procedure TopSecret; 
private 
    procedure DirtyLaundry; 
protected 
    procedure ResistantToChange; 
end; 

que sé Puedo acceder al método privado si tengo el código fuente agregando una clase descendiente en la misma unidad.

Tengo 2 preguntas:
- ¿Cómo empleo un ayudante de clase para acceder al miembro strict private?
- ¿Puedo usar un ayudante de clase en una unidad separada para acceder (estrictamente) a miembros privados?

+0

Véase también esta cuestión de forma: [Access-A-estricta protegido-propiedad-de-uno-delphi clase] (http://stackoverflow.com/questions/8330003/access-a-strict-protected-property-of-a-delphi-class) –

Respuesta

36

hasta, e incluyendo Delphi 10,0 Seattle, se puede utilizar un ayudante de clase para acceder a strict protected y strict private miembros, así:

unit Shy; 

interface 

type 
    TShy = class(TObject) 
    strict private 
    procedure TopSecret; 
    private 
    procedure DirtyLaundry; 
    protected 
    procedure ResistantToChange; 
    end; 

unit NotShy; 

interface 

uses 
    Shy; 

type 
    TNotShy = class helper for TShy 
    public 
    procedure LetMeIn; 
    end; 

implementation 

procedure TNotShy.LetMeIn; 
begin 
    Self.TopSecret; 
    Self.DirtyLaundry; 
    Self.ResistantToChange; 
end; 

end. 

uses 
    ..., Shy, NotShy; 

procedure TestShy; 
var 
    Shy: TShy; 
begin 
    Shy := TShy.Create; 
    Shy.LetMeIn; 
    Shy.Free; 
end; 

Sin embargo, comenzando con Delphi 10.1 Berlin, esto ya no funciona! Los ayudantes de clase ya no pueden acceder a los miembros strict protected, strict private o private. Esta "característica" era en realidad un error del compilador que Embarcadero ya ha corregido en Berlín. Estás fuera de suerte.

+1

JFTR: en D2007, 'Self.DirtyLaundry;' y 'Self.ResistantToChange;' las líneas no se compilan mientras 'Self.TopSecret;' ** does **. Es decir. usted tiene acceso a miembros 'estrictamente privados' pero no a miembros' privados' o 'protegidos'. :-D –

+7

+1 para nombrar, hilarante !! (: – ComputerSaysNo

+0

Gracias, solo para ser claros, en D2007 el ayudante solo me permitirá acceder a miembros 'estrictamente privados' como este, en Delphi 2010 y hasta el asistente me permitirá acceder a todos los miembros de la clase. ¿Correcto? – Johan

6

Se eliminó el acceso a private y strict private miembros de una clase con class helpers en Delphi 10.1 Berlin. Ver Closing the Class Helpers Private Access Loophole.

Pero todavía hay una laguna abierta:

unit Shy; 

interface 

type 
    TShy = class(TObject) 
    strict private 
    procedure TopSecret; 
    private 
    procedure DirtyLaundry; 
    protected 
    procedure ResistantToChange; 
    end; 

implementation 

procedure TShy.DirtyLaundry; 
begin 
    WriteLn('DirtyLaundry'); 
end; 

procedure TShy.ResistantToChange; 
begin 
    WriteLn('ResistantToChange'); 
end; 

procedure TShy.TopSecret; 
begin 
    WriteLn('TopSecret'); 
end; 

end. 

Program TestClassHelpers; 

{$APPTYPE CONSOLE} 

Uses 
    Shy; 

type 
    TNotShy = class helper for TShy 
    public 
    procedure LetMeIn; 
    end; 

procedure TNotShy.LetMeIn; 
var 
    P : procedure of object; 
begin 
    TMethod(P).Code := @TShy.TopSecret; 
    TMethod(P).Data := Self; 
    P; // Call TopSecret 
    TMethod(P).Code := @TShy.DirtyLaundry; 
    TMethod(P).Data := Self; 
    P; // Call DirtyLaundry; 
    Self.ResistantToChange; // Protected access works without problems 
end; 

var 
    myObj: TShy; 
begin 
    myObj := TShy.Create; 
    try 
    myObj.LetMeIn; 
    ReadLn; 
    finally 
    myObj.Free; 
    end; 
end. 
+1

Usted acaba de hacer mi día. Eso es brillante. – Johan

+3

Me temo que esto no reemplaza la antigua "característica" por completo, porque solo le da acceso a los métodos, no a los campos. Antes de Delphi 10.1 Berlin, también podíamos acceder a campos privados de esa clase. – Alexandre

+0

Para obtener acceso a los campos privados, consulte [¿Cómo acceder a los métodos privados sin ayudantes?] (Http://stackoverflow.com/a/37761852/576719). Al usar una combinación de ayudantes de clase y RTTI, es posible conservar el rendimiento. –

Cuestiones relacionadas