了解以下lambda

时间:2010-11-16 05:30:10

标签: c# .net

我有像

这样的方法
void Test(Func<bool> f)
{
    f.Invoke();
}

我传递了Test( ()=>GetItem("123") )

f.Invoke()实际上调用了GetItem("123")

我想知道f知道GetItem有参数吗?

4 个答案:

答案 0 :(得分:4)

您的函数Test将函数作为参数。它将调用作为参数传递的任何函数。

在这种情况下,当您创建lambda () => GetItem("123")时,您正在创建一个不带参数的函数,并调用GetItem("123")

Test不知道传递给GetItem的参数的值,也不需要,因为参数的值在lambda中是硬编码的。

答案 1 :(得分:3)

你的问题有点令人困惑。 F不知道Getitem需要什么。

创建lambda时,会将“指针”返回到方法所在的内存中的位置。该方法包含返回Getitem(“123”)的代码行。 当你调用F时,实际发生的是一种跳转到指针。 F就像是指向函数所在内存中那个位置的“指针”。

所以,为了回答你的问题,F不知道Getitem需要什么,F只是调用你写的函数,而且该函数的“123”参数是硬编码的。

请记住lambda是一种Delegate

答案 2 :(得分:2)

好问题。你可以想到代表

() => GetItem("123")

作为以下表达式树的编译版本

Expression.Lambda<Func<bool>>(
    Expression.Call(
        null,
        typeof(X).GetMethod("GetItem"),
        new Expression[] { Expression.Constant("123", typeof(string)) }
    ), 
    new ParameterExpression[0]
);

这里我假设GetItem是在类X中定义的方法,并且其返回类型声明为bool

关键是委托捕获了需要调用的所有信息。在Test中调用此委托时,您不知道方法GetItem是在幕后,还是使用参数"123"调用它。代表正在跟踪该信息,Test对这些细节不可知。它只是想要它可以调用的东西最终返回bool。在您的特定实例中,bool碰巧是GetItem("123")的结果。

  

f.Invoke()实际上调用了GetItem("123")

实际上没有。它调用() => GetItem("123")只返回GetItem("123")的值。看到区别?

答案 3 :(得分:2)

您传递给Test的内容是parameter-less delegate,它会调用您的GetItem方法。 因此,Test方法对GetItem的参数一无所知。它只知道它正在呼叫的delegate

Test( ()=>GetItem("123") )

等于

Test(delegate { return GetItem("abc") ; } );

就像打电话

Test(MyMethod)   
...
bool MyMethod()
{
    return GetItem("123");
}