I came across a situation where i need some knowledge.
Below is the code:
// A function to match the delegate
public static int DoSomething()
{
Console.WriteLine("i am called");
return 1;
}
// Usage
Action action = () => DoSomething();
Func<int> func = () => DoSomething();
action();
func();
My understanding of Action
used to be that it should match a delegate that accepts no parameter and returns nothing.
And for Func<int>
that it should match a delegate that accepts no parameter and returns an int
.
DoSomething
method returns an integer, hence my question: () => DoSomething()
is a delegate that returns an int
. Func
works as expected, but Action
doesn't. Why? What am i failing to understand here?
The code compiles and runs properly, both output i am called
. What i want to know is that why Action action = () => DoSomething();
is not a compile time error?
Actions can only take input parameters, while Funcs can take input and output parameters. It is the biggest difference between them. An action can not return a value, while a func should return a value in the other words.
Action is a delegate type defined in the System namespace. An Action type delegate is the same as Func delegate except that the Action delegate doesn't return a value. In other words, an Action delegate can be used with a method that has a void return type. For example, the following delegate prints an int value.
Func<T, TResult> defines a function that accepts one parameter (of type T) and returns an object (of type TResult). In your case, if you want a function that takes a Person object and returns a string...you'd want Func<Person, string> which is the equivalent of: string Function(Person p) { return p.Name; }
Func is a delegate (pointer) to a method, that takes zero, one or more input parameters, and returns a value (or reference). Predicate is a special kind of Func often used for comparisons (takes a generic parameter and returns bool).
What i want to know is that why
Action action = () => DoSomething();
is not a compile time error?
It compiles because you've got a lambda expression that calls the method but ignores the result. You couldn't use a method group conversion, e.g.
// Compile-time failure
// error CS0407: 'int Test.DoSomething()' has the wrong return type
Action action = DoSomething;
(The same method group conversion for Func<Action, int>
is fine.)
But instead, you're doing something more like this:
Action action = DoSomethingAndIgnoreResult;
...
private static void DoSomethingAndIgnoreResult()
{
DoSomething(); // Hey, I'm ignoring the result. That's fine...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With