【问题标题】:How to get the equivalent of a static(class) field in Delphi?如何在 Delphi 中获得等效的静态(类)字段?
【发布时间】:2012-01-02 15:57:02
【问题描述】:

我在一个非常昂贵的课程中进行了某项操作。 (完全运行大约需要 8 秒)所以,现在我决定它应该在程序开始时在“初始化”屏幕期间运行。但是,我在 Delphi 中找不到任何地方表明存在静态字段之类的东西。

我基本上需要做的是加载一个记录列表并在程序的整个生命周期中保持它们的活力。在 Delphi 中执行此操作的最佳方法是什么?

我会在 C# 中非常简单地做到这一点:

class Foo{
  static List<...> Bar;
}

但是在 Delphi 中,我没有看到任何用于创建静态字段的内容。我看到的只是用于创建静态方法的class 关键字

【问题讨论】:

  • 在现代 Delphi 中,您可以使用 class var 来获得等效的静态成员字段,但在 Delphi 7 中,您需要使用全局变量。
  • class 方法和static 方法相似,但略有不同。 class 方法接收调用它们的类作为隐式参数,类似于实例方法接收实例的方式。 static 方法没有接收到这样的参数。旧版本的 Delphi 只有 class 方法,但我认为新版本也有 static 方法以提高 .net 兼容性。
  • @CodeInChaos 我不知道distinction。这是相当深奥的,因为类方法的 Self 参数的等价物很容易在 static 方法中获得。但是使用Self 确实可以避免重复自己。附言您是正确的,D7 没有 class var,我正要在您的原始答案中对此发表评论,但您的宽限期编辑清除了它!
  • 用静态模拟非虚拟类方法需要引入一个额外的参数,因为self 参数指向调用该方法的类,它可能是一个子类。虚拟类方法根本没有直接的映射。自从我迁移到 C# 后,我有时会错过类方法,而 C# 没有它们。
  • @code 啊,我没有想过从派生类甚至实例方法中调用类方法。顺便别忘了在 cmets 中@收件人

标签: delphi oop static delphi-7


【解决方案1】:

你可以只使用一个全局变量。将其添加到单元的implementation 部分,使其成为该单元的本地。

我的 Turbo Delphi 支持 class var x:integer;,但我很确定 Delphi 7 不支持。

【讨论】:

    【解决方案2】:

    我认为这是在 Delphi 中使用 initializationfinalization 的好时机。这在一个单元的末尾,就在end. 之前你可以使用它来创建/释放这样的全局实例,或者只是设置默认变量......

    unit Unit1;
    
    interface
    
    uses
      Classes;
    
    function MyList: TStringList;    
    
    implementation
    
    var
      GMyList: TStringList;
    
    function MyList: TStringList;
    begin
      Result:= GMyList;
    end;
    
    initialization
      GMyList:= TStringList.Create;
      MyList.Append('Value 1'); 
      MyList.Append('Value 2');
      MyList.Append('Value 3');
    
    finalization
      GMyList.Free;
    
    end.
    

    这只需要像这样的特殊场景。 MyList 将在您的申请期间有效。

    注意GMyList 是如何在implementation 下声明的,MyList 实际上是一个访问GMyList 的全局函数。这是为了避免意外分配等。从任何其他单元,您可以使用MyList 函数访问GMyList,但不能直接访问GMyList(这是您要避免错误的地方)。

    【讨论】:

    • 建议:将 MyList 移到实现中,并通过函数将其公开,以防止意外写入访问。 (添加/更改项目仍然是可能的,但恶意/错误代码不能简单地重新分配它)
    • F前缀是成员,G更合适
    • @DavidHeffernan 以前从未听说过...有什么好的资源可以查看前缀示例吗?
    • 德尔福源代码。就我个人而言,我从未见过全局的 G 前缀。我的观点是,你必须有一个前缀 G 将是明显的候选人。它不能是 F,因为那是字段。我有时会在我的实现部分全局变量前加上 _
    • G在这种情况下代表Global,而F代表Field,这不是我在这种情况下所拥有的。这就是大卫的观点。我不怀疑_ 是否是一种更标准的做法,但我不喜欢前缀_ 的样子,所以我会坚持使用G :)
    【解决方案3】:

    如果你想要真正的东西,你需要一个更新的 Delphi 版本。

    然而,pascal 一直有类似的作用域,但为此您应该(有点幻想)将单元视为静态最终类。

    公共的函数和变量在接口部分定义,私有的东西在实现部分定义。 所有这些都或多或少相当于类变量和类方法。

    如果您将您的单元命名为 loader.pas,并在接口部分定义了一个函数“init”,您甚至可以像调用类函数一样调用它:loader.init()。

    初始化和终结部分相当于类构造函数和类析构函数。

    我上面描述的内容从 turbo plascal 到 delphi 2007 都是有意义的(我认为类变量是在 d2009 中引入的)。总而言之,我建议您购买更新的 delphi。

    【讨论】:

    • Turbo Delphi 有类变量,它基于 delphi 2006。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-10
    • 1970-01-01
    • 2010-10-12
    • 1970-01-01
    • 2017-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多