3

このユニットをコンパイルする場合:

unit Test;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
  private
    class var StartDate, EndDate: TDateTime;   // Line 12
    fTest: TNotifyEvent;
  public
    property OnTest: TNotifyEvent read fTest;  // Line 15.
  end;

implementation

{$R *.dfm}

end.

次のコンパイラエラーが発生します。

[DCCエラー]Test.pas(15):E2356プロパティアクセサーはインスタンスフィールドまたはメソッドである必要があります

しかし、12行目をコメントアウトすると、正常にコンパイルされます。誰かが理由を説明できますか?日付間隔を格納するためのクラス変数として日付が必要です。

4

2 に答える 2

8

そのエラーは自明であるはずです。それを分解してみましょう。

プロパティアクセサーは、インスタンスフィールドまたはメソッドである必要があります。

プロパティアクセサは、に続く式readです。プロパティが書き込み可能である場合、に続く式writeもプロパティアクセサーになります。

したがって、コードでは、プロパティアクセサーはfTestです。

インスタンスフィールドは、クラスの通常のフィールドです。したがって、クラスフィールドは修飾されません。同様に、インスタンスメソッドはクラスのプレーンメソッドです。クラスメソッドはインスタンスメソッドではありません。実際、クラスメソッドではないメソッドはすべてインスタンスメソッドです。

したがって、エラーはfTest、がインスタンスフィールドではないことを示します。

そしてそれは正しいです。クラスフィールドです。

private
  class var StartDate, EndDate: TDateTime;   
  fTest: TNotifyEvent; // class var applies to fTest also

fTestクラスフィールドになるつもりはないと思います。次のようにクラスを作成する必要があります。

TForm1 = class(TForm)
private
  class var StartDate, EndDate: TDateTime;   
private
  fTest: TNotifyEvent;
public
  property OnTest: TNotifyEvent read fTest;  
end;

多分:

TForm1 = class(TForm)
private
  class var
    StartDate, EndDate: TDateTime;   
  var 
    fTest: TNotifyEvent;
public
  property OnTest: TNotifyEvent read fTest;  
end;

クラスフィールドとインスタンスフィールドをより明確に区別できるので、前者の方が好きです。

于 2012-11-06T17:53:11.613 に答える
2

はフィールドにclass var拡張されfTest、クラスフィールドになります。その場所を避けるために、var前に単純な場所を置きfTestます。

于 2012-11-06T18:24:15.437 に答える