C# Eval() 支持

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1024070/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:46:26  来源:igfitidea点击:

C# Eval() support

c#eval

提问by Adi Barda

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 evalability? so we won't have to do the parsing ourself. How do microsoft do this in their immediate window or watch windows?

我们需要在运行时评估对象中的值,而我们有一个确切成员路径的文本语句,例如:myobject.firstMember.secondMember[3].text
我们考虑使用正则表达式解析此文本语句,然后评估文本值通过使用反射,但在我们这样做之前,我想知道 C# 是否支持某种eval能力?所以我们不必自己进行解析。微软如何在他们的直接窗口或观察窗口中做到这一点?

thanks you very much,

非常感谢你,

Adi Barda

阿迪巴尔达

采纳答案by Alex Yakunin

Probably the easiest way is to use DataBinder.Evalfrom System.Web.UI:

可能最简单的方法是使用System.Web.UI 中的DataBinder.Eval

var foo = new Foo() { Bar = new Bar() { Value = "Value" } };
var value = DataBinder.Eval(foo, "Bar.Value");

回答by Vilx-

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.

AFAIK 没有这样的内置 Eval 函数。你必须走正则表达式+反射的方式。我也认为 Visual Studio 也在做同样的事情。

回答by Marc Gravell

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 CsharpRepland 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.

在未来(大约 5.0 时间范围内),“编译器即服务”可能能够做到这一点。实际上,您现在可以使用“mono”来做很多事情(请参阅CsharpReplMono.CSharp- 但是,我希望它需要了解更多有关上下文的信息才能在其中使用局部变量等Evaluate) - 但在当前的 MS .NET 产品中没有任何支持。

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/PropertyDescriptorrather than direct reflection, but the effect is the same.

现在,您必须做一些类似于许多数据绑定代码所做的事情……用诸如“。”之类的标记将其分开。并使用反射。严格来说,绑定代码实际上是使用TypeDescriptor/PropertyDescriptor而不是直接反射,但是效果是一样的。

回答by Mark Seemann

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.

尽管是一种重量级的方法,但您可以使用 C# CodeDom 来发出一个新的新程序集,其中包含仅具有该行代码的方法。

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#.

我承认,这比其他一些建议要严厉得多,但另一方面,您让 C# 解析器完成繁重的工作,因此只要它是有效的 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.

如果你走那条路,你还需要确保你可以再次卸载发出的程序集,所以创建和卸载 AppDomains 可能是必要的。

I have successfully implemented and used the above technique. On the other hand, if you can use a DynamicMethodit 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.

我已经成功地实现并使用了上述技术。另一方面,如果您可以使用DynamicMethod,它会轻得多。但是,我从未尝试过这种方法,所以我不能说您是否可以使用 C# 文字实现 DynamicMethod 的主体。

回答by Tracker1

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...

这是我用来查找动态嵌套属性的类似内容。

  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;
  }

回答by John Saunders

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.

实际上,Windows Workflow Foundation 的表达式计算和规则引擎功能可以做这样的事情。请参阅Windows Workflow Foundation 规则引擎简介

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.

关于这些组件的一个有趣的事情是,它们的设计使您可以在自己的应用程序中托管设计时组件,以设计在您自己的自定义类的上下文中运行的规则和/或表达式集。例如,你告诉它设计一个针对“myObject”的表达式,它会知道有一个 firstMember,它有一个 secondMember,它有一个索引器,产生一个具有 text 属性的类型。您可以将表达式和规则保存为 XML,并在运行时读取它们,而无需在运行时使用设计器。

In particular, see External RuleSet Toolkit Sample.

特别是,请参阅外部规则集工具包示例

回答by David Wynne

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

您可以随时尝试我的轻量级 C# Eval 程序。它将 C# 语言的一个重要子集编译为动态方法。我的 GitHub 存储库DavidWynne/CSharpEval上的完整详细信息

回答by xnaterm

Unfortunately, C# doesn't have any native facilities for doing exactly what you are asking.

不幸的是,C# 没有任何本机设施可以完全满足您的要求。

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# 代码。它提供在运行时评估 C# 代码并支持许多 C# 语句,包括像“ myobject.firstMember.secondMember[3].text”这样的表达式。实际上,此代码可在任何 .NET 项目中使用,但仅限于使用 C# 语法。查看我的网站http://csharp-eval.com了解更多详细信息。

回答by Davide Icardi

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 Treeswithout using compilation or reflection.

我编写了一个开源项目Dynamic Expresso,它可以将使用 C# 语法编写的文本表达式转换为委托(或表达式树)。表达式在不使用编译或反射的情况下被解析并转换为表达式树

You can write something like:

你可以这样写:

var interpreter = new Interpreter();
var result = interpreter.Eval("8 / 2 + 2");

or

或者

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);

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.

我的工作基于 Scott Gu 文章http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx