删除已发布的空白部分总是安全的吗?

Is it always safe to remove a published empty section?

我正在处理一个旧的遗留项目,该项目有几个 类,其中 published 部分总是声明时没有任何内容,即:

TMyClass = class
public
   procedure DoSomething();
published
end;

编译时,我收到以下警告消息:

[DCC Warning] uMyUnit.pas(141): W1055 PUBLISHED caused RTTI ($M+) to be added to type 'TMyClass'

我不知道前任开发者是否出于某种正当理由声明了这些 published 部分。 删除空的 published 部分是否总是安全的,或者它是否会导致应用程序的行为发生一些变化?

视情况而定

代码的其余部分是否真的需要为 class 访问 RTTI?

只有 TPersistent-derived classes 默认应用 {$M+} directlive,不需要 published 部分。

published 部分用于 DFM 流,这需要 RTTI。非持久性 classes 不在 DFM 中蒸煮,但 RTTI 有其他用途。

因此,在不知道其余代码的作用的情况下,并不知道删除空的 published 部分是否安全。

class 本身的区别是 none - 然而重要的是任何 class 的默认可见性继承自 class 和 {$M+} 然后从 public 变为 published!

查看示例代码:

uses
  TypInfo;

type
  TMyClass = class
  private
    fName: string;
    property Name: string read fName;
  published
  end;

  TMyOtherClass = class(TMyClass)
    property Name;
  end;

var
  propCount, i: Integer;
  props: PPropList;
begin
  propCount := GetPropList(TypeInfo(TMyOtherClass), props);
  for i := 0 to propcount - 1 do
    Writeln(props^[i].Name);
  Readln;
end.

您可以看到它列出了 Name 属性 但是当您从 TMyClass 中删除已发布的内容时它不会 - 这是因为一旦 TMyClass 得到 {$M+} 添加了任何声明的成员,但没有明确说明它将被发布的可见性反对 public。

还将发布其他声明为不可见的成员,例如字段。这正在流式系统中使用 Delphi 用于表单等。 例如,您可以调用 TObject.FieldAddressTObject.MethodAddress 传递字段或方法的名称,并返回指向该字段或方法的指针。它仅适用于已发布的字段和方法。

这就是从 dfm 加载如何设置所有那些 IDE 生成的字段,如 Button1 或将 Button1Click 方法连接到 Button1.OnClick - 它们没有显式继承自 TComponent 的表单顶部的可见性已声明 {$M+}