WinRT C# 动态表达式计算器
WinRT C# dynamic expression evaluator
我的应用程序要求在 WinRT c# 应用程序运行时评估字符串表达式。
以下是一些示例表达式:
strObj.Substring(10) + strObj.Substring(strObj.Length - 3)
'001' + strObj.Substring(3) + '003'
注意:以上表达式将在后端定义,应用程序应在运行时根据用户输入进行计算。
我查看了 DynamicExpresso、NReco 和其他一些在 WinRT 环境下工作的表达式求值器 none。 WinRT 中是否有可用的框架?或者我如何在代码中实现它?
WinRT 环境在编译为可移植 class 库 (PCL) 之前无法引用通常的 class 库。可移植库对框架 classes/methods 使用有很多限制(仅允许使用通常的 .NET classes 的子集);在大多数情况下,如果不额外采用这些限制,class 库无法编译为 PCL。
我调查了将 NReco LambdaParser 编译为 PCL 的可能性,并得到了积极的结果。 PCL-采用的版本不包括灵活的 NReco 类型转换器(它们基于 ITypeConverter/TypeDescriptor,不适用于 PCL),而是仅使用 Convert.ChangeType。
下载link:NReco LambdaParser Portable (with source code)
以下代码适用于 PCL 版本的 LambdaParser:
var lambdaParser = new LambdaParser();
Func<string,int,string> left = (s,n) => { return s.Substring(n); };
var vars = new Dictionary<string,object>() {
{"str1", "123456"},
{"str2", "123"},
{"Left", left} // custom function
};
var res = lambdaParser.Eval(
"str1.Substring(3)+\" \"+str2.Substring(str2.Length-2)+\" \"+Left(str1,1)", vars );
Console.WriteLine("Res: {0}", res);
如果您发现此 PCL 版本可用,我可能会在 GitHub 上发布其源代码并创建 Nuget 包。
您也可以尝试 DynLan - it also supports PCL / net3.5 / net.core (https://github.com/b-y-t-e/DynLan)。该库本身解析代码并逐行执行。这是您的表达式的小示例(结果 == "klmnoprstuwxyzxyz"):
var dict = new Dictionary<string, object>();
dict["strObj"] = "abcdefghijklmnoprstuwxyz";
object result = new Compiler().
Compile(@" strObj.Substring(10) + strObj.Substring(strObj.Length - 3) ").
Eval(dict);
您还可以在脚本中使用变量,例如(结果 == "ABCDEPRSTU"):
var dict = new Dictionary<string, object>();
dict["strObj"] = "abcdefghijklmnoprstuwxyz";
object result = new Compiler().
Compile(
@" a = strObj.Substring(0, 5).ToUpper(); " +
@" b = strObj.Substring(15, 5).ToUpper(); " +
@" a + b ").
Eval(dict);
我的应用程序要求在 WinRT c# 应用程序运行时评估字符串表达式。
以下是一些示例表达式:
strObj.Substring(10) + strObj.Substring(strObj.Length - 3)
'001' + strObj.Substring(3) + '003'
注意:以上表达式将在后端定义,应用程序应在运行时根据用户输入进行计算。
我查看了 DynamicExpresso、NReco 和其他一些在 WinRT 环境下工作的表达式求值器 none。 WinRT 中是否有可用的框架?或者我如何在代码中实现它?
WinRT 环境在编译为可移植 class 库 (PCL) 之前无法引用通常的 class 库。可移植库对框架 classes/methods 使用有很多限制(仅允许使用通常的 .NET classes 的子集);在大多数情况下,如果不额外采用这些限制,class 库无法编译为 PCL。
我调查了将 NReco LambdaParser 编译为 PCL 的可能性,并得到了积极的结果。 PCL-采用的版本不包括灵活的 NReco 类型转换器(它们基于 ITypeConverter/TypeDescriptor,不适用于 PCL),而是仅使用 Convert.ChangeType。
下载link:NReco LambdaParser Portable (with source code)
以下代码适用于 PCL 版本的 LambdaParser:
var lambdaParser = new LambdaParser();
Func<string,int,string> left = (s,n) => { return s.Substring(n); };
var vars = new Dictionary<string,object>() {
{"str1", "123456"},
{"str2", "123"},
{"Left", left} // custom function
};
var res = lambdaParser.Eval(
"str1.Substring(3)+\" \"+str2.Substring(str2.Length-2)+\" \"+Left(str1,1)", vars );
Console.WriteLine("Res: {0}", res);
如果您发现此 PCL 版本可用,我可能会在 GitHub 上发布其源代码并创建 Nuget 包。
您也可以尝试 DynLan - it also supports PCL / net3.5 / net.core (https://github.com/b-y-t-e/DynLan)。该库本身解析代码并逐行执行。这是您的表达式的小示例(结果 == "klmnoprstuwxyzxyz"):
var dict = new Dictionary<string, object>();
dict["strObj"] = "abcdefghijklmnoprstuwxyz";
object result = new Compiler().
Compile(@" strObj.Substring(10) + strObj.Substring(strObj.Length - 3) ").
Eval(dict);
您还可以在脚本中使用变量,例如(结果 == "ABCDEPRSTU"):
var dict = new Dictionary<string, object>();
dict["strObj"] = "abcdefghijklmnoprstuwxyz";
object result = new Compiler().
Compile(
@" a = strObj.Substring(0, 5).ToUpper(); " +
@" b = strObj.Substring(15, 5).ToUpper(); " +
@" a + b ").
Eval(dict);