I've been seing Func<> for sometime now, and I've manage to avoid it (for now). But, now it looks like I can't dodge it forever. For instance, I tried Dynamic Linq, but almost everything was in terms of Func<>. I've tried one of my book (C# 2008/Deitel&Deitel) and also MSDN but I'm not getting it yet. They all jump straight in the subject.
Thanks for helping
Func is a delegate that points to a method that accepts one or more arguments and returns a value. Action is a delegate that points to a method which in turn accepts one or more arguments but returns no value. In other words, you should use Action when your delegate points to a method that returns void.
As we know that, Func is a generic delegate so it is defined under System namespace. It can contain minimum 0 and maximum of 16 input parameters in it and contain only one out parameter. The last parameter of the Func delegate is the out parameter which is considered as return type and used for the result.
Action is a delegate (pointer) to a method, that takes zero, one or more input parameters, but does not return anything. Func is a delegate (pointer) to a method, that takes zero, one or more input parameters, and returns a value (or reference).
Func is a generic delegate included in the System namespace. It has zero or more input parameters and one out parameter. The last parameter is considered as an out parameter. This delegate can point to a method that takes up to 16 Parameters and returns a value.
Func<>
is a generic delegate - it is just very convenient to use, because you don't have to create your own delegate for each argument/return type combination.
Earlier, you had to write something like:
public delegate long MyDelegate( int number );
public void Method( IEnumerable<int> list, MyDelegate myDelegate )
{
foreach( var number in list )
{
myDelegate( number );
}
}
You had to publish your delegate so that a user can call your method correctly. Especially when you need a bunch of different delegates you ended up publishing one for every argument list and return type.
With Func<>
you just write:
public void Method( IEnumerable<int> list, Func<int, long> myDelegate )
{
foreach( var number in list )
{
myDelegate( number );
}
}
It means the same as the first code example - Func<int, long>
defines a delegate that takes one integer argument and returns a long value.
Of course you can use longer parameter lists, too: Func<int, int, bool, long>
will still return a long value while it takes two ints and a bool value. If you wish a delegate without return value you will have to use Action<>
, which will have void as a return type.
EDIT (by request): How to call the method in my example:
For the caller, there is no difference between the solution with MyDelegate
or Func<>
. In both cases he has three options to call the method:
Using a lambda notation (C# 3.0 required, probably the best solution for short methods):
Method( myList, i => i * i );
By using an anonymous method (C# 2.0 required):
Method( myList, delegate( int i )
{
return i * i;
} );
Or by using a real method as an argument:
Method( myList, Square );
private static long Square( int number )
{
return number * number;
}
Func<...>
is a family of delegate types, that return some value, and take some number of arguments; for example:
Func<int,bool>
is simply something that takes an int and returns a bool (the return is always at the end); for example a predicate:
int[] data = {1,2,3,4,5};
var odd = data.Where(i => i % 2 == 0);
Func<string>
is a method that returns string, such as () => "hello world";
.
Func<DateDtime, TimeSpan, DateTime>
might be something like (when,howLong) => when + howLong;
Likewise there is Action<...>
which does the same but without a return type.
There's nothing magic about Func<...>
- it is just a simpler way of expressing delegates, while a: using generics (useful for LINQ), or b: not needing you to look up what the arguments are; if the delegate type is something obscure (PipeStreamImpersonationWorker
for example) it can be hard to know what it takes; if that was expressed as the comparable Action
it would be clear that it takes no parameters and returns void
.
This might help. Suppose every time you see Func<int, string>
you think to yourself:
interface IFuncIntString
{
string Invoke(int x);
}
That is, the delegate is an object that implements this interface. It has a single method called Invoke which takes an int and returns a string.
Now add to that the feature that you can omit the "Invoke" on a call, and you've got yourself a delegate.
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