【问题标题】:Accessing private fields from a Class Helper从类助手访问私有字段
【发布时间】:2015-08-12 17:55:37
【问题描述】:

给定

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

在一个单元中

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;

另一方面,XE8 编译器报告错误“E2003 未声明的标识符 'FPrivateInt'。鉴于私有成员的可见性受限,这是我直觉上所期望的 在声明类的单元之外,如果我没有看到 Marco Cantu 的 Delphi 2007 Handbook of a class helper p89/90 上的示例 它访问“帮助”类的私有字段,也是一个明确的声明 在这个问题的公认答案的开头段落中

Can I call static private class method with class helper?

这似乎支持它:“众所周知,助手确实破解了私有可见性。因此,私有成员对类助手是可见的。......”

那么,为什么我会收到 E2003 Undeclared Identifier 错误?在我的理解或代码中,我显然在某处遗漏了一些东西。我在使用 XE4 和 XE6 时遇到了同样的错误,顺便说一句,XE4 早于我引用的 SO 答案,这是从去年开始的。

【问题讨论】:

  • 你可以访问私有方法,而不是字段。
  • @TLama:Marco Cantu 的示例肯定使用了字段。我有它在我面前。
  • 它可以使用members这个词,但是那里的所有代码(以及文本的意图)都演示了使用私有方法。还请查看 LURD 对同一问题的回答中引用的所有文档,所有这些都指私有 methodsfunctions
  • @DavidHeffernan:Arf。当然,我把它改成了备用腮红。
  • @Ken 如果您错过了解决方案,请注意,成员一词的使用是准确且有意的。私有字段,就像助手中的私有方法一样可见。

标签: delphi helper delphi-xe8


【解决方案1】:

下面概述的解决方案适用于 Delphi Seattle 及之前的版本。

由于我不知道的原因,您需要使用 Self 限定私有实例成员。所以,这编译:

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

与 cmets 中的建议相反,方法也是如此。您需要显式包含 Self. 才能在帮助对象中调用私有方法。

在 Delphi 10.1 Berlin 及更高版本中,不再可能访问助手中的被帮助者的 strict privateprivate 成员。

【讨论】:

  • 确实如此(编译)。我很困惑为什么 MC 应该选择一个示例,正如所写的那样,只有 Helper 和 Helped 在同一个单元中才有效。我认为这只是为了紧凑的插图。
  • 大概是 Marco 犯了一个错误。文档有点弱,不是吗。
  • 它只是为了尽可能简单的演示,但我同意它具有误导性。对于未来的版本,我将用受保护的替代私有。无论如何,该代码在柏林 10.1 中仍然有效,因为始终授予对同一单元中私有的访问权限,无论是否为类助手。
  • 严格保护的成员仍然可以从 Delphi 10.1 Berlin 中的助手访问。我从你的答案中删除了。
  • @LURD 谢谢。约翰写了那部分!
【解决方案2】:

致使用 Delphi 10.2/10.3 的用户 - 我在这里找到了一篇文章: How to access a private field from a class helper in Delphi 10.1 Berlin?

它声明使用with Self do 可以让您从类助手访问私有变量!我有一些使用 self.variable 的辅助类,它们给出了一个错误,我不允许访问私有区域。

with Self do 为我解决了这个问题! :) 所以如果你遇到这些问题.. 自己试试..

【讨论】:

  • 只是一个警告:这显然是一种被忽视的“破解”可见性的方式,就像“自我”一样。方法可能会在未来的 Delphi 版本中关闭。私人成员应该就是这样 - 私人......
  • 我同意 - 但我在 TZipFile 中使用了一个类助手,我需要访问一个私有变量才能删除 zipfile 中的文件。你也可以在 D10.1 之前编辑这些,所以我不完全理解他们为什么改变这个。
  • 他们改变了这一点,因为它不应该是可能的。私有成员应该是私有的。如果编译器不强制执行此操作,则这是一个需要修复的错误。就这么简单……
  • 那么最好的选择是什么?继承 ZipFile 类并创建一个 ZipFileEx 类而不是类助手?
  • 您有四个选择:1) 依靠编译器错误并按照您现在所做的那样做,知道修复错误只是时间问题,2) 希望作者修复/更新类,让你以适当的方式做你想做的事,3) 找到另一个库,让你做你需要的事,4) 在新的源文件中制作类的副本并自己进行更改。但请注意,在这种情况下,后代类对您没有帮助,因为私有成员就是这样 - 私有的。您需要保护它们才能在后代类中访问它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-07
  • 2012-03-13
  • 1970-01-01
  • 2021-12-15
  • 2013-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多