【问题标题】:Expression to string表达式到字符串
【发布时间】:2011-03-21 22:12:38
【问题描述】:

我怎样才能得到这样的字符串

Namespace.IMyService.Do("1")

来自此片段中演示的表达式:

IMyService myService = ...;
int param1 = 1;

myExpressionService.Get(c => myService.Do(param1));

我实际上不想调用Do,除非使用生成的字符串满足条件。

【问题讨论】:

  • 您的样本正确吗?你真的想要"1" 而不是1
  • Namespace.IMyService.Do("1") 看起来像一个表达式,而不是字符串。你想得到"Namespace.IMyService.Do(\"1\")"吗?
  • @Snowbear 是的 - 我想要每个参数的 ToString() 结果。
  • @Daniel:你的表达方式会一直是x => foo.method(closureVariable)吗?
  • 否 - 它应该灵活的参数数量。

标签: c# expression expression-trees


【解决方案1】:

你必须遍历Expression trees。下面是一些示例代码:

internal static class myExpressionService
{
    public static string Get(Expression<Action> expression)
    {
        MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body;
        var method = methodCallExpression.Method;
        var argument = (ConstantExpression) methodCallExpression.Arguments.First();

        return string.Format("{0}.{1}({2})", method.DeclaringType.FullName, method.Name, argument.Value);
    }
}

这样调用就可以了:string result = myExpressionService.Get(() =&gt; myService.Do(1));

输出为:Namespace.IMyService.Do(1)

您可以扩展/更新它以处理您的场景。

【讨论】:

  • 应该是 argument.Value.ToString() 和 \"{2}\"
  • @Chris, ToString 不需要。我还删除了引号以使其更易于阅读。无论如何,这并不完全是 OP 想要的,只是一个方向。
  • @Snowbear:我如何调用这个动作?
  • @Daniel, expression.Compile()() 将完成这项工作
  • 这会在我的机器上产生一个InvalidCastException——第一个参数是MemberExpression,而不是ConstantExpression
【解决方案2】:

这也可以(虽然不是特别优雅):

public static string MethodCallExpressionRepresentation(this LambdaExpression expr)
{
    var expression = (MethodCallExpression)expr.Body;

    var arguments = string.Join(", ", expression.Arguments.OfType<MemberExpression>().Select(x => {
        var tempInstance = ((ConstantExpression)x.Expression).Value;
        var fieldInfo = (FieldInfo)x.Member;
        return "\"" + fieldInfo.GetValue(tempInstance).ToString() + "\"";
    }).ToArray());

    return expression.Object.Type.FullName + "." + expression.Method.Name + "(" + arguments + ")";
}

你可以这样称呼它:

Expression<Action> expr = c => myService.Do(param1));
var repr = expr.MethodCallExpressionRepresentation();    // Namespace.IMyService.Do("1")

【讨论】:

    【解决方案3】:

    您应该能够在结果表达式上调用 .ToString()。根据 MS 文档 ToString() 返回表达式的文本表示。你试过吗?

    【讨论】:

    • 在这种情况下,它返回类似() =&gt; value(Namespace.Program+&lt;&gt;c__DisplayClass0).myService.Do(1) 的内容,但略有不同
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多