将C#函数调用转换为字符串

时间:2015-01-16 18:41:45

标签: c#

我想创建一个将“C#函数调用”转换为字符串的函数。 例如: 在我的C#项目中有一个公共函数,可以像这样调用:

myTestClass.myTestFunction();

这是一个没有参数和returnvalue的函数。 现在我想实现另一个接受C#的函数 “Expression”作为参数并将“Expression”转换为字符串:

Expression<Func<???>> expr = () => myTestClass.myTestFunction();
string myString="";
myString=convertExpressionToString(expr);

myString现在应该包含“myTestClass.myTestFunction();” 完整的函数调用包括类是很重要的 name在字符串中。

任何想法如何解决这个问题?

3 个答案:

答案 0 :(得分:4)

对于这种情况,你可以简单地写

private static string ConvertExpressionToString(LambdaExpression expr)
{
    var methodCallExpr = expr.Body as MethodCallExpression;
    if (methodCallExpr != null ) {
        return methodCallExpr.Method.DeclaringType.Name + "." +
            methodCallExpr.Method.Name + "();";
    }
}

一般情况比较复杂;但是,这可以让您了解从哪里开始。


更复杂的版本打印作为常量表达式传递的参数:

private static string ConvertExpressionToString(LambdaExpression expr)
{
    var sb = new StringBuilder();
    var methodCallExpr = expr.Body as MethodCallExpression;
    sb.Append(methodCallExpr.Method.DeclaringType.Name)
        .Append(".")
        .Append(methodCallExpr.Method.Name)
        .Append("(");
    var arguments = methodCallExpr.Arguments;
    for (int i = 0; i < arguments.Count; i++) {
        if (i > 0) {
            sb.Append(", ");
        }
        var constExpr = arguments[i] as ConstantExpression;
        if (constExpr == null) {
            sb.Append("<expr>");
        } else {
            sb.Append(constExpr.ToString());
        }
    }
    sb.Append(");");
    return sb.ToString();
}

它可以应付这个表达:

Expression<Action> expr = () => myTestClass.myTestFunction(5, "hello");

但是,由于参数可以是任何有效的表达式,因此包含其他情况很快变得复杂。然后有outref个参数和可选参数。

答案 1 :(得分:0)

只需在方法正文上致电ToString

string myString = expr.Body.ToString();

答案 2 :(得分:0)

你想要得到的是一个动作

Expression<Action> expr = () => myTestClass.myTestFunction();
MethodCallExpression mbr = (MethodCallExpression)expr.Body;
String methodName = mbr.Method.Name;
Assert.AreEqual(methodName, "myTestFunction");
MemberExpression me = (MemberExpression) mbr.Object;
String memberName = me.Member.Name;
Assert.AreEqual(methodName, "myTestClass");
String finalName = string.Format("{0}.{1}()", memberName, methodName);
Assert.AreEqual("myTestClass.myTestFunction()", finalName);

因为您通过闭包访问myTestClass,您需要意识到您通过成员表达式访问它 所以正文是一个方法调用。我们从中获取方法名称,然后我们得到表示我们正在调用方法的对象的表达式,我们将其转换为成员表达式,因为在这种情况下它就是这样,我们从成员那里得到名称成员表达。