Delphi中的静态属性

3
我遇到了一个与静态属性Calendar有关的问题。
type
  TDateTime = class(TObject)
  private
  class var fcalendar: TCalendar;
  class procedure SetCalendar(const Value: TCalendar);
  public
  class property Calendar: TCalendar read fcalendar write SetCalendar;
 end;

implementation

  class procedure TDateTime.SetCalendar(const Value: TCalendar);
  begin
    if Value <> nil then
    begin
      TDateTime.fcalendar := Value;
    end;
  end;

错误发生在第7行

E2355类属性访问器必须是类字段或类静态方法


2
注意,使用 TDateTime 声明类名可能会与 System.TDateTime 类型混淆。 - LU RD
1个回答

6
问题出在setter上,错误信息详细解释了如何修复它:将其标记为静态。这意味着您不能将虚拟类方法用作访问器,但您也没有这样做,所以这不应该是一个问题。
class procedure SetCalendar(const Value: TCalendar); static;

1
除了错误信息没有解释如何“修复”它,因为Delphi类方法默认是静态的,除非在方法声明后面有一个指定其他情况的关键字,例如virtual或dynamic。我已经使用Delphi 20年了,甚至不知道您可以在成员声明后添加static关键字。:( - Jon Robertson
@JonRobertson 类方法接收当前类的 Self 作为 TClass 引用。静态方法没有 Self - Mason Wheeler
我并不是在指"类方法"。那个短语可能会让人感到困惑,因为所有的方法都属于一个类,但是指定一个 Delphi 方法是"类方法"更接近于我"通常"(在 Delphi 之外)所称呼的"静态方法"。然而,答案提到了放置在方法声明后面的"static"关键字,而不是放置在方法声明前面的"class"关键字。一个带有"static;"的方法和一个没有的方法之间有什么区别? - Jon Robertson
我现在看到了“类方法”(在过程或函数之前用“class”关键字声明)和“类静态方法”(与先前相同,在声明后立即使用“static”关键字)之间的区别。与Delphi(可能还有Pascal)对静态方法的旧定义相比,这很令人困惑:http://docwiki.embarcadero.com/RADStudio/Seattle/en/Methods#Static_Methods。(其中指出“默认情况下方法是静态的”。 “静态方法”可用于指代两种不同的东西。 :() - Jon Robertson
请参阅http://docwiki.embarcadero.com/RADStudio/Seattle/en/Methods#Static_Methods。现在解释一下大多数类方法(静态而非虚拟或动态)和类静态方法之间的区别。在Delphi中,将这两个词颠倒过来具有完全不同的含义,当我遇到这个错误消息时感到困惑。 - Jon Robertson
@JonRobertson 哦,我明白你的意思了。术语混淆。普通方法是实例方法,而不是类方法——它们作用于对象实例,并将对象实例作为Self。如果它们没有标记为virtualdynamic,则它们会静态分派而不是动态分派。标记为class方法的方法作用于类,并将TClass引用作为Self,而不是对象实例。它们也可以具有静态或虚拟分派。但是使用static指令标记的类方法没有Self,因此无法进行虚拟分派。 - Mason Wheeler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接