C# Eval() 支持
我们需要在运行时评估对象中的值,同时我们有确切成员路径的文本语句,例如:myobject.firstMember.secondMember[3].text
我们想过使用正则表达式解析这个文本语句,然后使用反射评估文本值,但在我们这样做之前,我想知道 C# 是否支持某种 eval 能力? 所以我们不必自己进行解析。 微软如何在他们的直接窗口或监视窗口中做到这一点?
非常感谢你,
阿迪·巴尔达
we need to evaluate a value in an object in run time while we have a textual statement of the exact member path for example: myobject.firstMember.secondMember[3].text
we thought of parsing this textual statement using regex and then evaluate the text value by using reflection but before we do that i wonder if C# support some kind of eval ability? so we won't have to do the parsing ourself. How do microsoft do this in their immediate window or watch windows?
thanks you very much,
Adi Barda
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
可能最简单的方法是使用 DataBinder.Eval< /a> 来自 System.Web.UI:
Probably the easiest way is to use DataBinder.Eval from System.Web.UI:
我编写了一个开源项目 Dynamic Expresso,它可以将使用 C# 语法编写的文本表达式转换为委托(或表达式树)。 表达式被解析并转换为表达式树,而不使用编译或反射。
您可以这样写:
或者
我的工作基于 Scott Gu 文章 http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the- linq-dynamic-query-library.aspx 。
I have written an open source project, Dynamic Expresso, that can convert text expression written using a C# syntax into delegates (or expression tree). Expressions are parsed and transformed into Expression Trees without using compilation or reflection.
You can write something like:
or
My work is based on Scott Gu article 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
而不是直接反射,但效果是一样的。In the future (around the 5.0 timeframe), the "compiler as a service" may be able to do this. Actually, you may be able to do a lot of this now with "mono" (see CsharpRepl and Mono.CSharp - however, I expect it'll need to know a lot more about the context to be able to use local variables etc in
Evaluate
) - but there isn't any support for this in the current MS .NET offering.For now, you would have to do something like what a lot of the data-binding code does... split it apart by tokens such as "." and use reflection. Strictly speaking, the binding code actually uses
TypeDescriptor
/PropertyDescriptor
rather than direct reflection, but the effect is the same.尽管这是一种重量级方法,但您可以使用 C# CodeDom 发出一个新的程序集,其中包含仅包含该行代码的方法。
我承认,这比其他一些建议要严厉得多,但另一方面,您让 C# 解析器完成繁重的工作,因此只要它是有效的 C#,它就应该能够处理您扔给它的所有内容。 。
如果您采用这种方法,您还需要确保可以再次卸载发出的程序集,因此可能需要创建和卸载 AppDomain。
我已经成功地实施并使用了上述技术。 另一方面,如果您可以使用 DynamicMethod< /a> 它会更轻量。 但是,我从未尝试过这种方法,所以我不能说是否可以使用 C# 文字实现 DynamicMethod 的主体。
Although a somewhat heavy-weight approach, you can use C# CodeDom to emit a new a new assembly that contains a method with just that line of code.
This is much more heavy-handed than some of the other suggestions, I admit, but on the other hand you let the C# parser do the heavy lifting, so it should be able to handle everything you throw at it as long as it's valid C#.
If you go that route, you also need to ensure that you can unload the emitted assembly again, so creating and unloading AppDomains may be necessary.
I have successfully implemented and used the above technique. On the other hand, if you can use a DynamicMethod it would be much more light-weight. However, I have never tried that approach, so I can't say whether you can implement a DynamicMethod's body using C# literals.
实际上,Windows Workflow Foundation 的表达式求值和规则引擎功能可以做这样的事情。 请参阅Windows Workflow Foundation 规则引擎简介。
关于这些组件的一个有趣的事情是,它们的设计使您可以在自己的应用程序中托管设计时组件,以设计在您自己的自定义类的上下文中运行的规则和/或表达式集。 例如,您可以告诉它针对“myObject”设计一个表达式,并且它会知道有一个firstMember,它有一个secondMember,它有一个索引器,生成一个具有文本属性的类型。 您可以将表达式和规则保留为 XML,并在运行时读回它们,而无需在运行时使用设计器。
特别是,请参阅外部规则集工具包示例。
Actually, the expression evaluation and rules engine feature of Windows Workflow Foundation can do things like this. See Introduction to the Windows Workflow Foundation Rules Engine.
One interesting thing about these components is that they were designed so that you can host the design-time components in your own applications to design sets of rules and/or expressions that operate in the context of your own custom classes. For instance, you'd tell it to design an expression against "myObject", and it would know that there's a firstMember which has a secondMember which has an indexer yielding a type that has a text property. You can persist the expressions and rules as XML, and read them back at runtime, without needing to use the designer at runtime.
In particular, see External RuleSet Toolkit Sample.
不幸的是,C# 没有任何本机工具来准确执行您所要求的操作。
但是,我的 C# eval 程序确实允许评估 C# 代码。 它提供在运行时评估 C# 代码的功能,并支持许多 C# 语句,包括“myobject.firstMember.secondMember[3].text”等表达式。 事实上,此代码可在任何 .NET 项目中使用,但是它仅限于使用 C# 语法。 请访问我的网站 http://csharp-eval.com 了解更多详细信息。
Unfortunately, C# doesn't have any native facilities for doing exactly what you are asking.
However, my C# eval program does allow for evaluating C# code. It provides for evaluating C# code at runtime and supports many C# statements, including expressions like "myobject.firstMember.secondMember[3].text". In fact, this code is usable within any .NET project, however, it is limited to using C# syntax. Have a look at my website, http://csharp-eval.com, for additional details.
您随时可以尝试我的轻量级 C# Eval 程序。 它将 C# 语言的重要子集编译为动态方法。 我的 GitHub 存储库上的完整详细信息 DavidWynne/CSharpEval
You can always try my light-weight C# Eval program. It compiles a substantial subset of the C# language to dynamic methods. Full details on my GitHub repository DavidWynne/CSharpEval
AFAIK 没有这样的内置 Eval 函数。 你必须采用正则表达式+反射的方式。 我也认为 Visual Studio 也在做同样的事情。
AFAIK there is no such built-in Eval function. You'll have to go the Regex+Reflection way. I also think that Visual Studio is doing the same.
这是我用来查找动态嵌套属性的类似内容。您需要添加索引器的逻辑...以及一些额外的检查...我在调用方法中捕获空值/错误...
Here's something similar I'm using to find dynamically nested properties.. you'd need to addthe logic for indexers... and some extra checking... i'm catching nulls/errors in my calling method...