Accessing private fields from a Class Helper

2019-07-11 14:02发布

问题:

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.

回答1:

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.



回答2:

To users that use Delphi 10.2/10.3 - i found a article here: How to access a private field from a class helper in Delphi 10.1 Berlin?

Where it stated that using with Self do lets you access private variables from a class helper! I had some helper classes that used self.variable and those gave an error that im not allowed to access private area.

The with Self do fixed this for me! :) so if you run into these problems.. try it yourself..