トップへ(mam-mam.net/)

クラスのプライベートなメンバ変数を参照する ~Delphiソースコード集

検索:

クラスのプライベートなメンバ変数を参照する方法(RTTI又はクラスヘルパーを使う)

プライベートなメンバ変数を有するクラス

Unit2に以下のようなクラス「TTestClass」を作ります。
通常、このクラスのプライベートメンバ変数「fStringList」や「fString」は他のユニットから参照することはできません。

unit Unit2;

interface
uses System.Classes;

Type
  TTestClass=class(TObject)
    strict private
      //このクラスからのみ参照できる変数や関数の宣言
      fStringList:TStringList;
    private
      //同一ユニット内からのみ参照できる変数や関数の宣言
      fString:String;
    strict protected
      //このクラス、又は継承クラスからのみ参照できる変数や関数の宣言
    protected
      //同一ユニット内、又はこのクラス、又は継承クラスから
      //参照できる変数や関数を宣言
    public
      //どこからでも参照可能な変数や関数を宣言
      constructor Create(v:String);
      destructor Destroy;Override;
    published
      //どこからでも参照可能でRTTI情報が生成される変数や関数を宣言
  end;

implementation

constructor TTestClass.Create(v: String);
begin
  fStringList:=TStringList.Create;
  fStringList.Add(v+'(TStringList)');
  fString:=v+'(String)';
end;

destructor TTestClass.Destroy;
begin
  fStringList.Free;
  inherited;
end;

end.

RTTIを使ってプライベートなメンバ変数を参照する

以下ソースコードのようにTRttiContextを使うとUnit1からUnit2のクラス「TTestClass」のプライベートメンバ変数「fStringList」や「fString」を参照できます。

unit Unit1;

interface
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Rtti, Unit2;

・・・省略

implementation

procedure TForm1.Button1Click(Sender: TObject);
var Test:TTestClass;
    Context:TRttiContext;
    Stl:TStringList;
begin
  Test:=TTestClass.Create('Hello');
  try
    Context:=TRttiContext.Create;
    try
      //TTestClassのプライベート変数fStringListを参照
      Stl:=TStringList(
        Context.GetType(Test.ClassType).GetField('fStringList').GetValue(Test).AsObject
      );
      Memo1.Lines.Add(Stl[0]);
      //TTestClassのプライベート変数fStringを参照
      Memo1.Lines.Add(
        Context.GetType(Test.ClassType).GetField('fString').GetValue(Test).AsString
      );
    finally
      Context.Free;
    end;
  finally
    Test.Free;
  end;
end;

クラスヘルパーを使ってプライベートなメンバ変数を参照する

以下ソースコードのようにクラスヘルパーとSelfを使うとUnit1からUnit2のクラス「TTestClass」のプライベートメンバ変数「fStringList」や「fString」を参照できます。

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Unit2;

type
  ・・・省略

  //クラスヘルパーを用いる場合
  TTestClassHelper=class helper for TTestClass
    function GetFStringList():TStringList;
    function GetFString():String;
  end;

var
  Form1: TForm1;

implementation

procedure TForm1.Button2Click(Sender: TObject);
var Test:TTestClass;
begin
  Test:=TTestClass.Create('Hello');
  try
    //クラスヘルパーを用いて値を参照
    Memo1.Lines.Add( Test.GetFStringList()[0] );
    Memo1.Lines.Add( Test.GetFString() );
  finally
    Test.Free;
  end;
end;

{ TTestClassHelper }

function TTestClassHelper.GetFStringList: TStringList;
begin
  with Self do
    Result:=fStringList;
end;

function TTestClassHelper.GetFString: String;
begin
  with Self do
    Result:=fString;
end;

end.