我们需要在运行时评估对象中的值,同时我们有一个确切成员路径的文本语句,例如: myobject.firstMember.secondMember [3] .text
我们想过使用正则表达式解析这个文本语句,然后使用反射来评估文本值,但在我们这样做之前,我想知道C#是否支持某种 eval 能力?所以我们不必自己解析。微软如何在他们的直接窗口或观看窗口中执行此操作?
非常感谢你,
Adi Barda
答案 0 :(得分:17)
我编写了一个开源项目Dynamic Expresso,它可以将使用C#语法编写的文本表达式转换为委托(或表达式树)。表达式被解析并转换为Expression Trees而不使用编译或反射。
你可以这样写:
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。
答案 1 :(得分:16)
最简单的方法可能是使用System.Web.UI中的DataBinder.Eval:
var foo = new Foo() { Bar = new Bar() { Value = "Value" } };
var value = DataBinder.Eval(foo, "Bar.Value");
答案 2 :(得分:8)
将来(大约5.0时间范围内),“编译器即服务”可能能够做到这一点。实际上,你可以用“mono”来做很多事情(参见CsharpRepl和Mono.CSharp - 但是,我希望它能够更多地了解上下文在Evaluate
中使用局部变量等 - 但在当前的MS .NET产品中没有任何支持。
现在,您必须执行类似于许多数据绑定代码所做的事情......将它分开,例如“。”等标记。并使用反射。严格地说,绑定代码实际上使用TypeDescriptor
/ PropertyDescriptor
而不是直接反射,但效果是相同的。
答案 3 :(得分:1)
虽然是一种有点重量级的方法,但您可以使用C#CodeDom发出一个新的程序集,其中包含一个只包含该行代码的方法。
这比其他一些建议要严厉得多,我承认,但另一方面你让C#解析器完成繁重的工作,所以它应该能够处理你抛出的所有东西,只要它这是有效的C#。
如果你走这条路,你还需要确保你可以再次卸载发出的组件,因此可能需要创建和卸载AppDomains。
我已经成功实施并使用了上述技术。另一方面,如果你可以使用DynamicMethod,它会更轻盈。但是,我从未尝试过这种方法,所以我不能说你是否可以使用C#文字来实现DynamicMethod的主体。
答案 4 :(得分:1)
实际上,Windows Workflow Foundation的表达式评估和规则引擎功能可以做到这样的事情。请参阅Introduction to the Windows Workflow Foundation Rules Engine。
这些组件的一个有趣之处在于它们的设计使您可以在自己的应用程序中托管设计时组件,以设计在您自己的自定义类的上下文中运行的规则和/或表达式集。例如,你告诉它设计一个针对“myObject”的表达式,它会知道有一个firstMember,它有一个secondMember,它有一个索引器,产生一个具有text属性的类型。您可以将表达式和规则保存为XML,并在运行时将其读回,而无需在运行时使用设计器。
答案 5 :(得分:1)
您可以随时尝试我的轻量级C#Eval程序。它将C#语言的大部分内容编译为动态方法。我的GitHub存储库DavidWynne/CSharpEval
的完整详细信息答案 6 :(得分:1)
不幸的是,C#没有任何原生设施可以完全满足您的要求。
但是,我的C#eval程序允许评估C#代码。它提供了在运行时评估C#代码并支持许多C#语句,包括“ myobject.firstMember.secondMember [3] .text ”等表达式。实际上,此代码可在任何.NET项目中使用,但是,它仅限于使用C#语法。有关其他详细信息,请查看我的网站http://csharp-eval.com。
答案 7 :(得分:0)
AFAIK没有这样的内置Eval功能。你必须采用正则表达式+反射方式。我也认为Visual Studio也在做同样的事情。
答案 8 :(得分:0)
这里有类似我用来查找动态嵌套属性的东西..你需要为索引器添加逻辑......还有一些额外的检查......我在调用方法中捕获空值/错误...
public static object FindDottedProperty(this object input, string propertyName) { if (input == null) return null; if (string.IsNullOrEmpty(propertyName)) return null; Queue props = new Queue(propertyName.Split('.')); if (props.Count == 0) return null; //start with input object and roll out property stack from there. object ret = input; while (props.Count > 0) { var prop = props.Dequeue(); if (string.IsNullOrEmpty(prop)) return null; /*** ADD INDEXER LOGIC HERE ***/ //get the property's value based on the current named item ret = ret.GetType().GetProperty(prop).GetValue(ret, null); if (null.Equals(ret)) return null; } //return looked up value return ret; }