0

RTTI を有効にしてコンパイルされたクラスを使用して、ユーザーが式を定義できるようにするというタスクに直面しています。簡単に言いますと。

TAnimal = class(TPersistent)
private
  fWeight : Double;
  fHeight : Double;
  fName : string;
published
  property Weight : Double read fWeight write fWeight;
  property Height : Double read fHeight write fHeight;
  property Name : string read fName write fName;
end;

そして、指定された式で動物を評価するルーチンがあります

function EvaluateAnimal(const animal : TAnimal; expression : string) : Double;
begin
  //Result :=  Turn expression to evaluation and give the result
end;

ユーザー表現は (TAnimal.Weight * TAnimal.Height)/(TAnimal.Weight + TAnimal.Height)

これで、RTTI コンテキストを使用して TAnimal を取得し、動物の身長と体重の値を取得できます。ただし、ユーザーが提供した式をどのように評価できますか??

アプリケーションの起動時と実行時にユーザー式を準備するために使用できるメカニズムはありますか? 動物のインスタンスを送信して値を取得するだけです。ユーザーはいつでも式を自由に変更でき、アプリケーションは式を評価する必要があります。

Delphi XE3 を使用しています。

4

1 に答える 1

2

Live Binding を使用して式を評価できます。以下に簡単な例を示します。

program BindingsDemo;
{$APPTYPE CONSOLE}

uses
  System.Rtti,
  System.Bindings.Expression,
  System.Bindings.EvalProtocol,
  System.Bindings.Helper;

type
  TFoo = class
    Val1: Integer;
    Val2: Integer;
    Result: TValue;
  end;

procedure Main;
var
  Foo: TFoo;
  scope: IScope;
  expr: TBindingExpression;
begin
  Foo := TFoo.Create;
  Foo.Val1 := 42;
  Foo.Val2 := 666;
  scope := TBindings.CreateAssociationScope([Associate(Foo, 'Foo')]);
  expr := TBindings.CreateUnmanagedBinding(
    [Scope],
    'Foo.Val1 + Foo.Val2',
    [Scope],
    'Foo.Result',
    nil
  );
  expr.Evaluate;
  Assert(Foo.Result.AsInteger=708);
  Writeln(Foo.Result.ToString);
end;

begin
  Main;
  Readln;
end.

オブジェクトを解放するコードを意図的に省略したため、このコードが漏れていることに注意してください。そうすることにしたのは、式の評価の側面に集中できるようにするためです。

于 2013-05-20T14:24:09.100 に答える