Dynamic Expresso 試用紀錄
dynamic expression, 動態運算式, 動態表達式,
引言
偶而會有動態表達式的需求。
關鍵知識
發現一個不錯的方案:Dynamic Expresso。支授二種使用方式:
一、Eval, 每次都重新解析運算式並執行。若跑重複的運算式就較慢。
二、Parse & Invok, 解析運算式拿到 lambda;之後再執行此 lambda。這樣跑重複的運算就較快。
參數代入有二種方法
一、Varialbe, 為 Interpreter 的共享變數;可讓之下全部的 expression 共用。
二、Parameter, 只針對每個 expression 有效。
試用紀錄
Eval
@using DynamicExpresso
<MudPaper role="panel">
<MudText Typo=Typo.h6>Eval</MudText>
<MudNumericField T="decimal" Label="foo" @bind-Value=foo />
<MudNumericField T="decimal" Label="bar" @bind-Value=bar />
<MudTextField Label="expression" @bind-Value=expression />
<MudButton Variant=Variant.Filled Color=Color.Primary OnClick=HandleEval>Eval</MudButton>
<MudText>message: @message</MudText>
</MudPaper>
@code {
string message = string.Empty;
decimal foo = 987654321m;
decimal bar = 7654321m;
string expression = "foo - bar";
async Task HandleEval()
{
try
{
message = "計算中...";
await Task.Yield();
//------ 關鍵程式碼 eval & apply
var result = new Interpreter().Eval(expression,
new Parameter("foo", foo),
new Parameter("bar", bar));
message = $"{result}";
}
catch (Exception ex)
{
message = $"出現例外: " + ex.GetType().Name + ", " + ex.Message;
}
}
}
Parse & Invoke
@using DynamicExpresso
<MudPaper role="panel">
<MudText Typo=Typo.h6>Parse & Invoke</MudText>
<MudNumericField T="decimal" Label="foo" @bind-Value=foo />
<MudNumericField T="decimal" Label="bar" @bind-Value=bar />
<MudTextField Label="expression" @bind-Value=expression />
<MudButton Variant=Variant.Filled Color=Color.Primary OnClick=HandleParse>Parse</MudButton>
<MudButton Variant=Variant.Filled Color=Color.Primary OnClick=HandleInvoke>Invoke</MudButton>
<MudText>message: @message</MudText>
</MudPaper>
@code {
string message = string.Empty;
decimal foo = 987654321m;
decimal bar = 7654321m;
string expression = "foo - bar";
Lambda? lambda = null;
async Task HandleParse()
{
try
{
message = "解析中...";
await Task.Yield();
var interpreter = new Interpreter();
//interpreter.SetVariable("foo", foo);
//interpreter.SetVariable("bar", bar);
//lambda = interpreter.Parse(expression);
//------ 關鍵程式碼 parse
lambda = interpreter.Parse(expression,
new Parameter("foo", typeof(decimal)),
new Parameter("bar", typeof(decimal)));
message = $"The lambda parsed.";
}
catch (Exception ex)
{
lambda = null;
message = $"出現例外: " + ex.GetType().Name + ", " + ex.Message;
}
}
async Task HandleInvoke()
{
try
{
message = "計算中...";
await Task.Yield();
if(lambda is null)
{
message = $"lambda 未解析無法計算。";
return;
}
//------ 關鍵程式碼 invoke
var result = lambda.Invoke(foo, bar);
message = $"{result}";
}
catch (Exception ex)
{
message = $"出現例外: " + ex.GetType().Name + ", " + ex.Message;
}
}
}
(EOF)
Last updated