题
这个问题在这里已经有答案了:
- 如何动态评估 C# 代码? 16 个答案
我们需要在运行时评估对象中的值,同时我们有确切成员路径的文本语句,例如: myobject.firstMember.secondMember[3].text
我们考虑使用正则表达式解析这个文本语句,然后使用反射评估文本值,但在我们这样做之前,我想知道 C# 是否支持某种类型 评估 能力?所以我们不必自己进行解析。微软如何在他们的直接窗口或监视窗口中做到这一点?
非常感谢你,
阿迪巴尔达
解决方案
可能最简单的方法是使用 数据绑定器.Eval 来自 System.Web.UI:
var foo = new Foo() { Bar = new Bar() { Value = "Value" } };
var value = DataBinder.Eval(foo, "Bar.Value");
其他提示
我写了一个开源项目, 动态浓缩咖啡, ,它可以将使用 C# 语法编写的文本表达式转换为委托(或表达式树)。表达式被解析并转换为 表达式树 不使用编译或反射。
你可以这样写:
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 产品对此不提供任何支持。
现在,您必须做一些类似于许多数据绑定代码所做的事情......将其拆分为“”。并使用反射。严格来说,绑定代码实际上使用的是 TypeDescriptor
/PropertyDescriptor
而不是直接反射,但效果是一样的。
尽管这是一种重量级方法,但您可以使用 C# CodeDom 发出一个新的程序集,其中包含仅包含该行代码的方法。
我承认,这比其他一些建议要严厉得多,但另一方面,您让 C# 解析器完成繁重的工作,因此只要它是有效的 C#,它就应该能够处理您扔给它的所有内容。 。
如果您走这条路,您还需要确保可以再次卸载发出的程序集,因此可能需要创建和卸载 AppDomain。
我已经成功地实施并使用了上述技术。另一方面,如果您可以使用 动态方法 它会更轻。但是,我从未尝试过这种方法,所以我不能说是否可以使用 C# 文字实现 DynamicMethod 的主体。
实际上,Windows Workflow Foundation 的表达式求值和规则引擎功能可以做这样的事情。看 Windows Workflow Foundation 规则引擎简介.
关于这些组件的一个有趣的事情是,它们的设计使您可以在自己的应用程序中托管设计时组件,以设计在您自己的自定义类的上下文中运行的规则和/或表达式集。例如,您可以告诉它针对“myObject”设计一个表达式,并且它会知道有一个firstMember,它有一个secondMember,它有一个索引器,生成一个具有文本属性的类型。您可以将表达式和规则保留为 XML,并在运行时读回它们,而无需在运行时使用设计器。
特别是,请参阅 外部规则集工具包示例.
不幸的是,C# 没有任何本机工具来准确执行您所要求的操作。
但是,我的 C# eval 程序确实允许评估 C# 代码。它提供在运行时评估 C# 代码的功能,并支持许多 C# 语句,包括诸如“myobject.firstMember.secondMember[3].text”。事实上,此代码可在任何 .NET 项目中使用,但是它仅限于使用 C# 语法。看看我的网站, http://csharp-eval.com, ,了解更多详细信息。
您随时可以尝试我的轻量级 C# Eval 程序。它将 C# 语言的重要子集编译为动态方法。我的 GitHub 存储库上的完整详细信息 大卫韦恩/CSharpEval
AFAIK 没有这样的内置 Eval 函数。你必须采用正则表达式+反射的方式。我也认为 Visual Studio 也在做同样的事情。
这是我用来查找动态嵌套属性的类似内容。您需要添加索引器的逻辑......以及一些额外的检查...我在调用方法中发现空值/错误...
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; }