Today I was thinking about declaring this:
private delegate double ChangeListAction(string param1, int number);
but why not use this:
private Func<string, int, double> ChangeListAction;
or if ChangeListAction
would have no return value I could use:
private Action<string,int> ChangeListAction;
so where is the advantage in declaring a delegate with the delegate
keyword?
Is it because of .NET 1.1, and with .NET 2.0 came Action<T>
and with .NET 3.5 came Func<T>
?
Declaring a delegate explicitly can help with some type checks. The compiler can make sure that the delegate assigned to the variable is intended to be used as ChangeListAction and not some random action that happens to be compatible with the signature.
However the real value of declaring your own delegate is that it gives it semantic meaning. A person reading the code will know what the delegate is doing by its name. Imagine if you had a class with three int fields but instead you declared an array of three int elements. The array can do the same thing but the names of the fields bring semantic information that is useful to the developers.
You should use Func, Predicate and Action delegates when you are designing a general purpose library like LINQ. In this case the delegates do not have a predefined semantics other than the fact that they will execute and action or be used as a predicate.
On a side note there is a similar tradeoff issue with Tuple vs anonymous type vs declaring your own class. You could just stick everything in a Tuple but then the properties are just Item1, Item2 which tells nothing about the use of the type.
As MSDN said,
Func<>
is itself pre-definedDelegate
. For the first time, I confused about this stuff. After the experimental, my understanding was quite clearer. Normally, in C#, we can seeThe same concept is applied to
The difference between these to things is
Delegate
do not possess the concept of OOP, for example,Inheritance
. To make this things clearer, I did the experimental withMany build-in methods in framework (for example, LINQ), receive the parameter of
Func<>
delegate. The thing we can do with this method isFor example, from the code above I add more code
For better and more elaborate answer look at @nawfal. I will try to be more simplistic.
You are declaring a member of a class so you should stick with delegate. Using
delegate
is more descriptive and structural.Action/Func
types are made for passing around so you should use them more as parameters and local variables.And actually both of those are inheriting
Delegate
class. Action and Func are generic types and simplify creating delegates with different parameter types. And delegate keyword actually creates whole new class inheriting from Delegate in one declaration.The advantage is clarity. By giving the type an explicit name it is more clear to the reader what it does.
It will also help you when you are writing the code. An error like this:
is less helpful than one which says:
It also means that if you have two different delegates, both of which take the same types of parameters but conceptually do two entirely different things, the compiler can ensure that you can't accidentally use one where you meant the other.
Declare the delegate explicitly when you start to get too many parameters in the Func/Action, otherwise you keep having to look back, "What's the 2nd int mean again?"
I have found a special use case where you can only use delegate:
Using Func/Action just does not work:
'Namespace.Class.WndEnumProc' is a 'field' but is used like a 'type'
:Following code does compile, but throws exception when running because
System.Runtime.InteropServices.DllImportAttribute
does not support marshaling of generic types:I present this example to show to every one that: sometimes delegate is your only choice. And this is a reasonable answer to your question
why not use Action<T>/Func<T> ?