The advent of Action and Func family of delegates has rendered custom delegates less used, but the latter still finds uses. Advantages of custom delegates include:
-
As others have pointed, conveys intent clearly unlike generic
ActionandFunc(Patrik has a very good point about meaningful parameter names). -
You can specify
ref/outparameters unlike the other two generic delegates. For eg, you can havepublic delegate double ChangeListAction(out string p1, ref int p2);but not
Func<out string, ref int, double> ChangeListAction; -
Also, with custom delegates you need to write
ChangeListAction(I mean the definition) only once somewhere in your code base, whereas if you don’t define one you will have to litter everywhereFunc<string, int, double>all over. Changing the signature will be a hassle in the latter case – a bad case of not being dry. -
Can have optional parameters.
public delegate double ChangeListAction(string p1 = "haha", int p2);but not
Func<string, int, double> ChangeListAction = (p1 = "haha", p2) => (double)p2; -
You can have
paramskeyword for parameters of a method, not so withAction/Func.public delegate double ChangeListAction(int p1, params string[] p2);but not
Func<int, params string[], double> ChangeListAction; -
Well, if you’re truly out of luck and need parameters more than 16 (for the moment) 🙂
As to merits of Action and Func:
-
It’s quick and dirty, and I use it all over. It makes code short if the use-case is trivial (custom delegates have gone out of fashion with me).
-
More importantly, its type compatible across domains.
ActionandFuncare framework defined, and they operates seamlessly as long as the parameter types match. You can’t haveChangeSomeActionforChangeListAction.Linqfinds great use of this aspect.