gpt4 book ai didi

c# - 替换 lambda 表达式中的参数

转载 作者:太空狗 更新时间:2023-10-29 21:37:04 25 4
gpt4 key购买 nike

我有一部分代码在运行时接受 lambda 表达式,然后我可以编译和调用它。

Something thing;

Expression<Action<Something>> expression = (c => c.DoWork());
Delegate del = expression.Compile();
del.DynamicInvoke(thing);

为了节省执行时间,我将那些已编译的委托(delegate)存储在一个缓存中,一个 Dictionary<String, Delegate>其中键是 lambda 表达式字符串。

cache.Add("(Something)c => c.DoWork()", del);

对于完全相同的调用,它运行良好。但是我意识到我可以接收等效的 lambda,例如“d => d.DoWork()”,我实际上应该使用相同的委托(delegate),但我没有。

这让我想知道是否有一种干净的方法(阅读“不使用 String.Replace”,我已经将其作为临时修复)来替换 lambda 表达式中的元素,比如用 arg0 替换它们这样既可以

(c => c.DoWork())(d => d.DoWork())

被转换并比较为 (arg0 => arg0.DoWork())通过使用功能上类似于在 lambda 中注入(inject) Expression.Parameter(Type, Name) 的东西。

这可能吗? (答案可以包括 C#4.0)

最佳答案

我使用了字符串,因为这对我来说是最简单的方法。您不能手动更改参数表达式的名称(它具有“名称”属性,但它是只读的),因此您必须从片段中构造一个新的表达式。我所做的是创建一个“无名”参数(实际上,在这种情况下它获得一个自动生成的名称,即“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();
}

关于c# - 替换 lambda 表达式中的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2104449/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com