Delphiのクラスメソッドをクラス名とメソッド名を文字列で指定して実行する方法

Delphiのクラスメソッドをクラス名とメソッド名を文字列で指定して実行する。

unit Unit1;

interface

type
  TMyClass = class
  public
    // 引数のないクラスメソッド
    class procedure TestFunc1; static;
    // 引数のあるクラスメソッド
    class procedure TestFunc2(const S: string); static;
  end;

というユニットがあって、このUnit1のTMyClassのクラスメソッドを、次のようにクラス名とメソッド名を文字列で指定して実行する関数を作る。

  InvokeStatic('Unit1.TMyClass', 'TestFunc1', []);
  InvokeStatic('Unit1.TMyClass', 'TestFunc2', ['Test2']);

実装は次のようになる。

uses System.Rtti, System.TypInfo;

/// <summary>
/// クラスメソッドを実行する
/// </summary>
/// <param name="AClassName">
/// ユニット名.クラス名
/// </param>
/// <param name="AMetohdName">
/// メソッド名
/// </param>
/// <param name="Args">
/// メソッドの引数
/// </param>
procedure InvokeStatic(const AClassName, AMetohdName: string;
  const Args: array of TValue);
var
  RttiContext: TRttiContext;
  RttiType: TRttiType;
  Instance: TRttiInstanceType;
  Method: TRttiMethod;
begin
  // 「ユニット名.クラス名」から型を取得する
  RttiType := RttiContext.FindType(AClassName);
  // 取得した型がクラス型がどうか
  if (RttiType <> nil) and (RttiType.TypeKind = tkClass) then
  begin
    // TRttiInstanceTypeインスタンスにキャストする
    Instance := RttiType.AsInstance;
    // メソッド名からメソッドのRTTIオブジェクトを取得する
    Method := Instance.GetMethod(AMetohdName);
    // メソッドを実行する
    Method.Invoke(Instance, Args);
  end;
end;

プログラムの中でTMyClassが使用されていない場合は、コンパイル時の最適化によってTMyClassが削除されるため、TMyClassを使用するコードを含める必要がある。

Delphi XE6で確認しました。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください