在(Win32)Delphi中模拟类属性

时间:2013-05-01 14:43:28

标签: delphi delphi-xe2 static-methods

Simulating class properties in (Win32) Delphi中,有一个定义'class 属性'以及类方法的技巧:

unit myObjectUnit;

interface

type
  TMyObject = Class
  private
    class function GetClassInt: integer;
    class procedure SetClassInt(const Value: integer);
  public
    property ClassInt : integer read GetClassInt 
                                write SetClassInt;
  end;

implementation

{$WRITEABLECONST ON}
const TMyObject_ClassInt : integer = 0;
{$WRITEABLECONST OFF}

class function TMyObject.GetClassInt: integer;
begin
  result := TMyObject_ClassInt;
end;

class procedure TMyObject.SetClassInt(
  const Value: integer);
begin
  TMyObject_ClassInt := value;
end;

end.

我的代码中只有一个这样的对象,因此GetClassInt和SetClassInt始终在相同类型的常量* TMyObject_ClassInt *上运行的警告不适用:

procedure TForm1.Button1Click(Sender: TObject);
var
  myObject : TMyObject;
begin
  myObject.ClassInt := 2005;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  myObject : TMyObject;
begin
  ShowMessage(IntToStr(myObject.ClassInt));
end;

(这说明警告:单击1然后按2,消息显示2005,而不是0)。

然而,这段代码闻起来有点可疑。 我可以预期问题(除了上面的警告)吗? 有更好的方法吗?

顺便说一下,我不是在谈论蛮力$ WRITEABLECONST OFF - 而不是回到以前的状态。这可以通过以下方式规避:

{$IFOPT J-}
{$DEFINE WC_WAS_OFF}
{$ENDIF}
{$WRITEABLECONST ON}
const TMyObject_ClassInt : integer = 0;
{$IFDEF WC_WAS_OFF}
{$WRITEABLECONST OFF}
{$ENDIF}

3 个答案:

答案 0 :(得分:3)

这里需要指出一些事项:

首先,由于您已将此标记为XE2,因此它Class Properties正确支持Class Field Variables。自从(我认为)德尔福2009以来就是如此。

type
  TMyClass = class
    strict private
      class var         // Note fields must be declared as class fields
        FRed: Integer;
        FGreen: Integer;
        FBlue: Integer;
      public             // ends the class var block
        class property Red: Integer read FRed write FRed;
        class property Green: Integer read FGreen write FGreen;
        class property Blue: Integer read FBlue write FBlue;
  end;

可以加入:

TMyClass.Red := 0;
TMyClass.Blue := 0;
TMyClass.Green := 0;

对于旧版本的Delphi,这种解决方法是有效的,尽管我使用单位变量而不是Uli建议的可写常量。在所有情况下,您的主要问题是多线程访问。

答案 1 :(得分:1)

类字段现在支持一段时间了(我认为至少自Delphi 2009起),你声明它们就像

type
  TMyObject = Class
  public
    class var ClassInt : integer;
  end;

请参阅帮助中的Class Fields主题。

答案 2 :(得分:0)

此声明自Delphi-2009起有效:

type
  TMyObject = Class
  strict private
    class var
       MyClassInt : integer;
  private
    class function GetClassInt: integer; static;
    class procedure SetClassInt(const Value: integer); static;
  public
    class property ClassInt : integer read GetClassInt
                                write SetClassInt;
  end;

将您的类方法设为静态,并将您的属性声明为class property