I have been trying to figure this out and it's really bugging me. I have some code that looks like this
static T MyFunction<T>(Func<T> action, int i, int i2)
{
...some code here
}
When I need to call this code I tried this
var result = MyFunction<List<string>>(MethodThatReturnsListofString(int number), 1,2)
It fails stating that the best overload has invalid arguments But when I tried the following
var result = MyFunction<List<string>>(() => MethodThatReturnsListofString(int number), 1,2)
It works fine. What is the function of "() =>" in this case. I thought() could not be used with methods required more than 0 args.
This simply means that you are invoking an anonymous method which accepts 0 arguments. If its () => a+b
it returns the addition
else if you provide it a body
like ()=> { } its upto you to return or not
also if you provide the delegate which needs it to return then you have to return. for eg Action doesnt require but Func do require
is not a
Func<T>
. It is aFunc<T, U>
, whereList<string>
is one type argument andint
is the other. Moreover, you are providing the result of this method — not the method itself — as the argument to your function.On the other hand, this expression is a
Func<T>
:This is a lambda expression that creates a delegate with no input parameters and one output parameter (the
List<string>
). Thenumber
variable passed toMethodThatReturnsListofString()
is not part of the function definition. The code works because thenumber
variable is instead a closure. The variable is captured by the compiler and used by the method, but it's not part of the method signature.That is correct. But remember that the
Func<T>
type used for youraction
argument here defines a function that accepts 0 arguments and returns one value. So what you are doing is matching your expression to theFunc<T>
type ofMyFunction
'saction
parameter. Just because you then call a method that requires an argument within your newFunc<T>
delegate doesn't mean the delegate itself requires an argument.MyFunction<T>
expects as first parameter a method that takes no arguments and returns the typeT
.In your first attempt, you call
MethodThatReturnsListofString(number)
and try to provide the result (aList<T>
) as parameter instead of a method.In your second try, you create a method with the required signature by typing
() => MethodThatReturnsListofString(number)
and provide this as parameter.To make it more clear, you could have created a method like
and then called
With
() => MethodThatReturnsListofString
you declare an anonymous method inline and so you don't need to createMyAnonymousMethod
first. This part of your code is what is called a lambda expression.Note that by declaring this lambda,
MethodThatReturnsListofString
is not executed immediatly! It will be executed only whenMyFunction
really calls this action parameter likeYou're passing a lambda that takes no arguments.
That is the correct syntax to write such a lambda.
The fact that your lambda happens to call a function that takes arguments is completely irrelevant.