Search code examples
delphihelperdelphi-xe8

Accessing private fields from a Class Helper


Given

type
  TMyClass = class
  private
    FPrivateInt : Integer;
  protected
    FProtectedInt : Integer;
  public
    FPublicInt : Integer;
  end;

in one unit and

type
  TMyHelper = class helper for TMyClass
    function Sum : Integer;
  end;
[...]
function TMyHelper.Sum: Integer;
begin
  Result := 0;
  Result := Result + FPublicInt;
  Result := Result + FProtectedInt;
  Result := Result + FPrivateInt;  // <- compiler error here
end;

in another, the XE8 compiler reports error "E2003 undeclared identifier 'FPrivateInt'. This is what I would intuitively have expected, given the restricted visibility of private members outside the unit where a class is declared, if I hadn't seen the example on p89/90 of Marco Cantu's Delphi 2007 Handbook of a class helper which accesses private fields of the "helped" class and also an unequivocal statement in the opening paragraph of the accepted answer to this q

Can I call static private class method with class helper?

which seems to support it: "As is widely known, helpers do crack private visibility. So, private members are visible from a class helper. ..."

So, why do I get the E2003 Undeclared Identifier error? I am obviously missing something somewhere, in my understanding or code. I get the same error using XE4 and XE6, btw, and XE4 pre-dates the SO answer I've referenced, which is from last year.


Solution

  • The solution outlined below works for versions up to and including Delphi Seattle.

    For reasons unknown to me, you need to qualify private instance members with Self. So, this compiles:

    function TMyHelper.Sum: Integer;
    begin
      Result := 0;
      Result := Result + FPublicInt;
      Result := Result + FProtectedInt;
      Result := Result + Self.FPrivateInt;
    end;
    

    Contrary to the suggestions in the comments, the same is true for methods. You would need to explicitly include Self. to call a private method in the helpee.

    In Delphi 10.1 Berlin and beyond it is no longer possible to access strict private or private members of the helpee in a helper.