6

我有简单的 lambda 作为字符串:

var str = "f => f.Substring(0, f.IndexOf(' '))";

最终从传递的字符串中获取第一个单词。

将这种和平的字符串编译/转换为 Func 并使以下代码工作的最简单方法是什么。

Func<string, string> func = ...
var firstWord = func("Hello World");

表达会帮助我吗?将欣赏工作样品,

谢谢

4

4 回答 4

11

问题是这里没有强大的类型支持,所以你甚至不能使用表达式树。但是,DynamicLinq已经做到了这一点,因此您可以通过一些修改轻松地使其工作。只需在 DynamicExpression 类中创建一些您自己的静态方法来添加此功能:

public static Expression<Func<T, S>> ParseLambda<T, S>(string expression)
{
    string paramString = expression.Substring(0, expression.IndexOf("=>")).Trim();
    string lambdaString = expression.Substring(expression.IndexOf("=>") + 2).Trim();
    ParameterExpression param = Expression.Parameter(typeof(T), paramString);
    return (Expression<Func<T,S>>)ParseLambda(new[] { param }, typeof(S), lambdaString, null);
}

public static LambdaExpression ParseLambda(string expression, Type returnType, params Type[] paramTypes)
{
    string paramString = expression.Substring(0, expression.IndexOf("=>")).Trim("() ".ToCharArray());
    string lambdaString = expression.Substring(expression.IndexOf("=>") + 2).Trim();
    var paramList = paramString.Split(',');
    if (paramList.Length != paramTypes.Length)
        throw new ArgumentException("Specified number of lambda parameters do not match the number of parameter types!", "expression");

    List<ParameterExpression> parameters = new List<ParameterExpression>();
    for (int i = 0; i < paramList.Length; i++)
        parameters.Add(Expression.Parameter(paramTypes[i], paramList[i].Trim()));

    return ParseLambda(parameters.ToArray(), returnType, lambdaString, null);
}

两者的用法:

Func<string, string> func = DynamicExpression.ParseLambda<string, string>("f => f.Substring(0, f.IndexOf(\" \"))").Compile();

Func<string, int, string> otherFunc = ((Expression<Func<string, int, string>>)DynamicExpression.ParseLambda("(str, ind) => (ind * 100).ToString() + str")).Compile();

编辑:这还没有经过彻底的测试,所以你可能想通过一些单元测试来确保这些产生正确的结果。我没有做任何过于复杂的事情,只是明确声明要在public static LambdaExpression ParseLambda(ParameterExpression[] parameters, Type resultType, string expression, params object[] values)方法中使用的参数。
还修复了@Mauro Destro 指出的错误,方法是paramList在创建ParameterExpression.

于 2012-05-18T17:06:05.623 回答
6

您可以使用 Roslyn 脚本来执行此操作。例如:

var str = "f => f.Substring(0, f.IndexOf(' '))";
var func = await CSharpScript.EvaluateAsync<Func<string, string>>(str);
var firstWord = func("Hello World");

这需要Microsoft.CodeAnalysis.CSharp.Scripting包。

于 2017-05-16T22:34:43.017 回答
1

您将需要检查字符串并从提供的字符串构造一个表达式。没有简单的或内置的方法可以从这样的字符串中获取方法。

祝你好运。

于 2012-05-18T15:48:56.890 回答
0

您可能对 CodeDom 技术感兴趣。关联

但是,那里没有现成的解析器。

于 2012-05-18T15:52:20.273 回答