使用Delphi RTTI构建和评估表达式 [英] Building and evaluating expressions using Delphi RTTI

查看:50
本文介绍了使用Delphi RTTI构建和评估表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面临的任务是允许用户使用启用了RTTI的已编译类来定义表达式.让我以一种简单的方式来说明它.

I am faced with a task of allowing the user to define the expressions using the compiled classes with RTTI enabled. Let me put it in a simple way.

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;

我有一个例程,它将使用提供的表达式评估动物

And i have a routine which will evaluate the animal with the supplied expression

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,并获取动物的身高和体重的值.但是,如何评估用户提供的表达式?

Now, I can get the TAnimal using the RTTI Context and get the value of the animal's Height and Weight. However, how can i evaluate the expression what the user has supplied??

在我的应用程序启动时以及在运行时,是否可以使用任何机制来准备用户表达式,只需发送animal实例以检索值即可.用户可以随时更改表达式,应用程序必须评估表达式.

Is there any mechanism which i can use to prepare the user expression when my application starts and at runtime, just send the instance of animal to retrieve the value. The user is free to change the expression at anytime and the application has to evaluate the expression.

我正在使用Delphi XE3.

I am using Delphi XE3.

推荐答案

您可以使用实时绑定来计算表达式.这是一个简单的示例:

You can use Live Bindings to evaluate expressions. Here's a trivial example:

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.

注意,我故意省略了释放对象的代码,因此该代码泄漏了.我选择这样做是因为我们可以专注于表达评估方面.

Note, I've intentionally omitted the code to free objects and so this code leaks. I chose to do that so we could concentrate on the expression evaluation aspect.

这篇关于使用Delphi RTTI构建和评估表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆