Dyn*_*ard 6 c# lambda delegates expression
我有一部分代码在运行时接受lambda表达式,然后我可以编译和调用它.
Something thing;
Expression<Action<Something>> expression = (c => c.DoWork());
Delegate del = expression.Compile();
del.DynamicInvoke(thing);
Run Code Online (Sandbox Code Playgroud)
为了节省执行时间,我将这些已编译的委托存储在缓存中,Dictionary<String, Delegate>
其中键是lambda表达式字符串.
cache.Add("(Something)c => c.DoWork()", del);
Run Code Online (Sandbox Code Playgroud)
对于完全相同的调用,它工作正常.但是我意识到我可以收到相当的lambda,例如"d => d.DoWork()",我实际上应该使用相同的委托,而我不是.
这让我想知道是否有一种干净的方式(读取"不使用String.Replace",我已经将其作为临时修复)来替换lambda表达式中的元素,比如可能替换它们arg0
以便两者都可以
(c => c.DoWork())
和 (d => d.DoWork())
(arg0 => arg0.DoWork())
通过使用类似于在lambda中注入Expression.Parameter(Type,Name)的东西进行转换和比较.
那可能吗 ?(答案可以包括C#4.0)
我使用了字符串,因为这对我来说是最简单的方法。您无法手动更改参数表达式的名称(它具有“Name”属性,但它是只读的),因此您必须从片段构造一个新表达式。我所做的是创建一个“无名”参数(实际上,在本例中它获得一个自动生成的名称,即“Param_0”),然后创建一个与旧表达式几乎相同的新表达式,但使用新参数。
public static void Main()
{
String thing = "test";
Expression<Action<String>> expression = c => c.ToUpper();
Delegate del = expression.Compile();
del.DynamicInvoke(thing);
Dictionary<String, Delegate> cache = new Dictionary<String, Delegate>();
cache.Add(GenerateKey(expression), del);
Expression<Action<String>> expression1 = d => d.ToUpper();
var test = cache.ContainsKey(GenerateKey(expression1));
Console.WriteLine(test);
}
public static string GenerateKey(Expression<Action<String>> expr)
{
ParameterExpression newParam = Expression.Parameter(expr.Parameters[0].Type);
Expression newExprBody = Expression.Call(newParam, ((MethodCallExpression)expr.Body).Method);
Expression<Action<String>> newExpr = Expression.Lambda<Action<String>>(newExprBody, newParam);
return newExpr.ToString();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2305 次 |
最近记录: |