C#Eval()支持
我们需要在运行时评估对象中的值,同时我们有一个确切成员路径的文本语句,例如: myobject.firstMember.secondMember [3] .text
我们想过使用正则表达式解析这个文本语句,然后使用reflection来评估文本值,但在我们这样做之前,我想知道C#是否支持某种评估能力? 所以我们不必自己解析。 微软如何在他们的直接窗口或观看窗口中执行此操作?
非常感谢你,
阿迪巴尔达
可能最简单的方法是使用System.Web.UI中的DataBinder.Eval :
var foo = new Foo() { Bar = new Bar() { Value = "Value" } }; var value = DataBinder.Eval(foo, "Bar.Value");
我编写了一个开源项目Dynamic Expresso ,它可以将使用C#语法编写的文本表达式转换为委托(或表达式树)。 表达式被解析并转换为表达式树而不使用编译或reflection。
你可以这样写:
var interpreter = new Interpreter(); var result = interpreter.Eval("8 / 2 + 2");
要么
var interpreter = new Interpreter() .SetVariable("service", new ServiceExample()); string expression = "x > 4 ? service.SomeMethod() : service.AnotherMethod()"; Lambda parsedExpression = interpreter.Parse(expression, new Parameter("x", typeof(int))); parsedExpression.Invoke(5);
我的工作基于Scott Gu的文章http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx 。
在将来(大约5.0时间范围内),“编译器即服务”可能能够做到这一点。 实际上,你现在可以用“mono”做很多事情(参见CsharpRepl和Mono.CSharp – 但是,我希望它能够更多地了解能够使用局部变量等的上下文。 Evaluate
) – 但在当前的MS .NET产品中没有任何支持。
就目前而言,您必须执行类似于许多数据绑定代码所做的事情…将它分开,例如“。”等标记。 并使用reflection。 严格来说,绑定代码实际上使用TypeDescriptor
/ PropertyDescriptor
而不是直接reflection,但效果是一样的。
虽然是一种有点重量级的方法,但您可以使用C#CodeDom发出一个新的程序集,其中包含仅使用该行代码的方法。
我承认,这比其他一些建议要严厉得多,但另一方面,你让C#解析器完成繁重的工作,所以它应该能够处理你抛出的所有东西,只要它是有效的C# 。
如果您走这条路线,还需要确保可以再次卸载发出的组件,因此可能需要创建和卸载AppDomain。
我已经成功实现并使用了上述技术。 另一方面,如果你可以使用DynamicMethod它会更轻量级。 但是,我从未尝试过这种方法,所以我不能说你是否可以使用C#文字来实现DynamicMethod的主体。
实际上,Windows Workflow Foundation的表达式评估和规则引擎function可以做到这样的事情。 请参阅Windows Workflow Foundation规则引擎简介 。
关于这些组件的一个有趣的事情是它们的设计使您可以在自己的应用程序中托管设计时组件,以设计在您自己的自定义类的上下文中运行的规则和/或表达式集。 例如,你告诉它设计一个针对“myObject”的表达式,它会知道有一个firstMember,它有一个secondMember,它有一个索引器,产生一个具有text属性的类型。 您可以将表达式和规则保存为XML,并在运行时将其读回,而无需在运行时使用设计器。
特别是,请参阅External RuleSet Toolkit Sample 。
不幸的是,C#没有任何原生设施来完全按照你的要求去做。
但是,我的C#eval程序允许评估C#代码。 它提供了在运行时评估C#代码并支持许多C#语句,包括“ myobject.firstMember.secondMember [3] .text ”之类的表达式。 实际上,此代码可在任何.NET项目中使用,但是,它仅限于使用C#语法。 有关其他详细信息,请访问我的网站http://csharp-eval.com 。
你可以随时尝试我的轻量级C#Eval程序。 它将C#语言的大部分内容编译为动态方法。 我的GitHub存储库DavidWynne / CSharpEval的完整详细信息
AFAIK没有这样的内置Evalfunction。 你必须采用正则表达式+reflection方式。 我也认为Visual Studio也在做同样的事情。
这里有类似我用来查找动态嵌套属性的东西..你需要为索引器添加逻辑……还有一些额外的检查……我在调用方法中捕获空值/错误…
public static object FindDottedProperty(此对象输入,字符串propertyName) { if(input == null) return null; if(string.IsNullOrEmpty(propertyName)) return null; 队列道具=新队列(propertyName.Split('。')); if(props.Count == 0)返回null; //从输入对象开始并从那里推出属性堆栈。 object ret = input; 而(props.Count> 0) { var prop = props.Dequeue(); if(string.IsNullOrEmpty(prop))返回null; / ***在这里添加索引逻辑*** / //根据当前命名项获取属性的值 ret = ret.GetType()。GetProperty(prop).GetValue(ret,null); if(null.Equals(ret))返回null; } //返回查找值 返回; }