将C#函数调用转换为字符串
我想创建一个将“C#函数调用”转换为字符串的函数。 例如: 在我的C#项目中,有一个公共函数,可以这样调用:将C#函数调用转换为字符串,c#,C#,我想创建一个将“C#函数调用”转换为字符串的函数。 例如: 在我的C#项目中,有一个公共函数,可以这样调用: myTestClass.myTestFunction(); 它是一个没有参数和返回值的函数。 现在我想实现另一个接受C的函数# “表达式”作为参数,并将“表达式”转换为字符串: Expression<Func<???>> expr = () => myTestClass.myTestFunction(); string myString=""; myStr
myTestClass.myTestFunction();
它是一个没有参数和返回值的函数。
现在我想实现另一个接受C的函数#
“表达式”作为参数,并将“表达式”转换为字符串:
Expression<Func<???>> expr = () => myTestClass.myTestFunction();
string myString="";
myString=convertExpressionToString(expr);
Expression只需在方法体上调用ToString
string myString = expr.Body.ToString();
对于这种情况,您可以简单地编写
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();
}
private静态字符串ConvertExpressionToString(LambdaExpression expr)
{
var sb=新的StringBuilder();
var methodCallExpr=expr.Body作为MethodCallExpression;
sb.Append(methodCallExpr.Method.DeclaringType.Name)
.附加(“.”)
.Append(methodCallExpr.Method.Name)
.附加(“(”);
var arguments=methodCallExpr.arguments;
for(int i=0;i0){
某人加上(“,”);
}
var constExpr=参数[i]为常量表达式;
if(constExpr==null){
某人加上(“”);
}否则{
sb.Append(constExpr.ToString());
}
}
某人加上(“);”;
使某人返回字符串();
}
它可以处理这个表达:
Expression<Action> expr = () => myTestClass.myTestFunction(5, "hello");
expressionexpr=()=>myTestClass.myTestFunction(5,“hello”);
但是,由于参数可以是任何有效的表达式,因此包含其他情况很快就会变得复杂。然后是out
和ref
参数和可选参数。您试图得到的是一个动作
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);
Expression expr=()=>myTestClass.myTestFunction();
MethodCallExpression mbr=(MethodCallExpression)expr.Body;
字符串methodName=mbr.Method.Name;
AreEqual(methodName,“myTestFunction”);
MemberExpression me=(MemberExpression)mbr.Object;
字符串memberName=me.Member.Name;
AreEqual(methodName,“myTestClass”);
String finalName=String.Format(“{0}.{1}()”,memberName,methodName);
AreEqual(“myTestClass.myTestFunction()”,finalName);
因为您是通过闭包访问myTestClass的,所以您需要意识到您是通过成员表达式访问它的
所以主体是一个方法调用。我们从中获取方法名称,然后获取表示调用方法的对象的表达式,我们将其转换为成员表达式,因为在本例中就是这样,我们从该成员表达式的成员中获取名称。您可能需要使用nameof()等待c#6
function我不认为使用BCL有一个简单的解决方案,但是有一些第三方库支持使用C#语法打印表达式。搜索“反射”和“成员表达式”。这种类型的问题以前在这里已经回答过。它打印表达式的字符串表示,但输出不是一个正确的C#表达式。不确定OP.@CodesInChaos是否可以接受。他在哪里说输出应该是C#表达式?对于给定的表达式,他说输出应该是myTestClass.myTestFunction()代码>。这将为该格式的输入创建结果。嗯,刚刚选中。它不包括静态方法的类名。非常感谢:您的解决方案解决了我的问题@在_VI_地图上,单击答案左侧的复选标记来标记解决方案。