22

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

非常感谢你,

阿迪巴尔达

4

9 回答 9

20

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

var foo = new Foo() { Bar = new Bar() { Value = "Value" } };
var value = DataBinder.Eval(foo, "Bar.Value");
于 2009-06-21T16:57:57.833 回答
19

我编写了一个开源项目Dynamic Expresso,它可以将使用 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

于 2013-02-03T09:35:58.040 回答
8

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

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

于 2009-06-21T14:53:55.957 回答
1

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

于 2010-06-09T04:26:40.567 回答
1

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

我承认,这比其他一些建议要严厉得多,但另一方面,你让 C# 解析器完成繁重的工作,所以只要它是有效的 C#,它应该能够处理你扔给它的所有东西.

如果您走这条路,您还需要确保可以再次卸载发出的程序集,因此可能需要创建和卸载 AppDomain。

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

于 2009-06-21T15:04:01.270 回答
1

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

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

特别是,请参阅External RuleSet Toolkit Sample

于 2009-06-21T15:25:32.570 回答
1

不幸的是,C# 没有任何本机工具可以完全按照您的要求进行操作。

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

于 2011-06-10T02:35:43.627 回答
0

AFAIK 没有这样的内置 Eval 函数。您必须采用 Regex+Reflection 的方式。我也认为 Visual Studio 也在做同样的事情。

于 2009-06-21T14:48:49.663 回答
0

这是我用来查找动态嵌套属性的类似内容..您需要为索引器添加逻辑...以及一些额外的检查...我在调用方法中捕获了空值/错误...

  public static object FindDottedProperty(this object input, string propertyName)
  {
    如果(输入==空)
      返回空值;

    if (string.IsNullOrEmpty(propertyName))
      返回空值;

    队列道具 = new Queue(propertyName.Split('.'));
    if (props.Count == 0) 返回空值;

    //从输入对象开始并从那里推出属性堆栈。
    对象 ret = 输入;
    while (props.Count > 0)
    {
      var prop = props.Dequeue();
      if (string.IsNullOrEmpty(prop)) 返回空值;

      /*** 在此处添加索引器逻辑 ***/

      //根据当前命名项获取属性值
      ret = ret.GetType().GetProperty(prop).GetValue(ret, null);

      if (null.Equals(ret)) 返回空值;
    }

    //返回查找的值
    返回 ret;
  }
于 2009-06-21T15:11:06.857 回答