I have a method like
void Test(Func<b开发者_JAVA技巧ool> f)
{
f.Invoke();
}
I pass in the Test( ()=>GetItem("123") )
f.Invoke()
actually called GetItem("123")
.
I want to know how does f
know GetItem
has a parameter?
Your function Test
takes a function as a parameter. It will invoke whatever function is passed in as an argument.
In this case, when you create your lambda () => GetItem("123")
, you are creating a function that takes no arguments, and invokes GetItem("123")
.
Test
has no knowledge about the value of the parameter passed to GetItem
, nor does it need to, because the value of the parameter is hardcoded in the lambda.
You're question is a bit confusing. F doesn't know what's required by Getitem.
When you created the lambda, a "pointer" was returned to the place in the memory where a method is located. That method contains the line of code return Getitem("123"). When you invoke F, what actually happens is a kind of jump to a pointer. F is like a "pointer" to that place in the memory where the function is located.
So, to answer your question, F doesn't know what Getitem needs, F just calls the function your wrote, and that function has the "123" parameter hard coded.
Remember that lambda is a type of Delegate
What you are passing to Test
is a parameter-less delegate
which calls your GetItem
method.
So your Test
method does not know anything about parameters to GetItem
. It only knows about the delegate
it is calling.
Test( ()=>GetItem("123") )
is equal to
Test(delegate { return GetItem("abc") ; } );
which is like calling
Test(MyMethod)
...
bool MyMethod()
{
return GetItem("123");
}
Good question. You can think of the delegate
() => GetItem("123")
as being a compiled version of the following expression tree
Expression.Lambda<Func<bool>>(
Expression.Call(
null,
typeof(X).GetMethod("GetItem"),
new Expression[] { Expression.Constant("123", typeof(string)) }
),
new ParameterExpression[0]
);
Here I am assuming that GetItem
is a method defined in a class X
and that its return type is declared as bool
.
The point is that the delegate captures all the information it needs to be invoked. When you invoke this delegate in Test
, you have no idea that the method GetItem
is behind the scenes, or that it is being invoked with the parameter "123"
. The delegate is keeping track of that information and Test
is agnostic to those details. It just wants something that it can invoke that ultimately returns a bool
. In your particular instance, that bool
happens to be the result of GetItem("123")
.
f.Invoke()
actually calledGetItem("123")
Actually it didn't. It called () => GetItem("123")
which merely returns the value of GetItem("123")
. See the difference?
精彩评论