在 Delphi 中,如何使类型只能在 class 的 functions/methods 之间通过

In Delphi, how do I make a type passable only between functions/methods of a class

我目前有以下代码;

   interface

   {...}   

   type
      TMyRecord = record
        List : TShellList;
        Tree : TShellTree;
        Image : TImage;
      end;

      TSDIAppForm = class(TForm)
        { Published declarations }
      private
        function GetChildren(Sheet : TTabSheet) : TMyRecord;
      public
        { Public declarations }
      end;

据我了解,这意味着 TMyRecord 是对整个程序可见的全局类型。该类型只需要在 class 中可见,尽管该类型的对象确实需要作为参数传递并返回到 class 的 "private" functions/procedures 之间。我怎样才能做到这一点?我无法在 class 接口的 "private" 部分下声明类型,如果我在实现中声明它,那么我不相信在接口函数原型中使用它是可见的。此外,我认为 implements/interface 比 class 与单位内的可见性更相关。我是否需要以其他方式声明 GetChildren() 函数?

Per Uwe,只需在私人部分声明即可。在 XE8 中测试。以下作品

  TSDIAppForm = class(TForm)
  private
  type
    TMyRecord = record
      List : TShellList;
      Tree : TShellTree;
      Image : TImage;
    end;

    function GetChildren(Sheet : TTabSheet) : TMyRecord;
  public
    { Public declarations }
  end;

如其他答案所述,在支持嵌套类型的 Delphi 版本中,您可以简单地在所需范围和可见性内声明类型。

对于 Delphi 的旧版本,您可以通过使用未类型化的 var 参数来避免必须在 您单位的接口部分:

TSDIAppForm = class(TForm)
  ..
  procedure GetChildren(Sheet : TTabSheet; var aRecord);
  ..
end;

为了在方法的实现中方便和声明类型强制执行,您可以使用 absolute 声明来创建一个局部变量作为无类型参数的占位符:

procedure TSDIAppForm.GetChildren(    Sheet : TTabSheet; 
                                  var aRecord);
var
  result: TMyRecord absolute aRecord;
begin
  result.List := ...;
  // etc
end;

在这种情况下,由于该函数没有直接的 return 值并以直接类似的方式使用 var 参数,您可以选择使用名称 result,如图所示。或者你当然可以为你喜欢的局部变量使用任何其他名称。

在使用中,您只需像往常一样在 var 参数中使用适当的变量调用此方法:

var
  myRec: TMyRecord;
begin
  ..
  sdiForm.GetChildren(someSheet, myRec);
  ..
end;

通过这种方式,您可以将 实现 细节的类型真正限制在单元的 实现 部分。

注意: 此技术在键入 var 参数可能导致编译器抱怨 'formal var parameter types not matching'.[= 的情况下也很有用。 45=]

您当然应该始终仔细考虑它们是否是正确的方法。尤其是因为无论何时使用无类型参数,您当然都承担了确保代码类型安全的更大责任。滥用的可能性应该是显而易见的,但它们有时也会提供优势(在这种情况下,从接口部分完全删除一个类型,可以说最恰当地完全限制在实现部分)。

如果您创建的代码可能希望提供给旧版本 Delphi 的用户(其中​​私有类型等不可用),请记住它们也是一个有用的工具。