2012-05-18 48 views
3

我有簡單的lambda作爲一個字符串:轉換串入FUNC

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

這eventualy需要從所傳遞的字符串第一個字。

什麼是最簡單的方法來編譯/轉換這種和平的字符串到Func並使下面的代碼工作。

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

Will Expression能幫助我嗎?會明白工作的樣品,

感謝

+0

因此,你需要C#中的'eval()... – undefined

+0

哪個事件會從傳遞的字符串中獲取第一個字「 - 不,它不會。它將所有的文本提交到第一個空格字符。如果第一個字符是空格,您將得到一個空字符串。如果有一個詞,一個回車,一個詞,一個空格,你會得到前兩個詞。 –

+0

您是否嘗試過ExpressionTree而不是字符串? – Tarik

回答

2

你將需要檢查的字符串,並根據提供的字符串構建一個表達。沒有簡單內置方法從這樣的字符串中獲取方法。

祝你好運。

0

您可能感興趣的CodeDom技術。 link

雖然這裏沒有準備好的解析器。

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)方法中使用的參數。
修復了在創建​​時修改參數名稱paramList並修復了@Mauro Destro指出的錯誤。

+0

這應該被標記爲答案,接受的答案應該被刪除。 –

+0

此解決方案的工作原理!但是,必須更改參數解析器,因爲它在逗號後面以空格失敗 –

1

您可以使用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包。

相關問題