12

Which one is better in, say, parameter type in a method (not related to LINQ). Apparently Func is better since it's simpler, more descriptive, and if everyone is using this everything will become compatible (good). However I notice Microsoft uses its own delegate at some libraries, for example event handlers. So, what are the advantages and drawbacks of either of them? when should I use it?

Edits:

  • Apparently Func<> was only available in 3.5, so this can possible be the main reason that I saw non-Func delegates. Any other reason to not use Func? (example: this is from .NET4)

  • The same question also applies for Action<>

Louis Rhys
  • 34,517
  • 56
  • 153
  • 221
  • Which libraries? probably those libraries is old and developed prior to .Net 3.5(esp for EventHandler) – Jahan Zinedine Dec 16 '10 at 07:45
  • mostly in event handlers, but I also saw it in other libraries, I'll try to recall – Louis Rhys Dec 16 '10 at 07:48
  • `Func<>` did not exist until .net 3.5. Most event handler prior to that. – J-16 SDiZ Dec 16 '10 at 07:57
  • @Louis Rhys: Reflector .NET 'renders' all delegates (incl Func) as `delegate`. Perhaps you saw it there. – leppie Dec 16 '10 at 07:58
  • hmm that makes sense. any other reasons to not use Func<>? – Louis Rhys Dec 16 '10 at 07:58
  • http://msdn.microsoft.com/en-us/library/system.activities.bookmarkcallback.aspx this is from .NET 4, it is equivalent to Action – Louis Rhys Dec 16 '10 at 08:03
  • @Louis Rhys: Equivalent, but not typesafe. A lambda or delegate will be correctly converted by the compiler to that delegate type. You cannot however use an `Action` instance in place of that. There are ways to convert this at runtime however. Look at `Delegate.CreateDelegate`. – leppie Dec 16 '10 at 08:06
  • I could not. But Microsoft could have used `Action` isntead of that as parameter types instead of BookmarkCallback and then we don't need BookmarkCallback do we? – Louis Rhys Dec 16 '10 at 08:10
  • @Louis Rhys: They could have, at compile time it does not really make so much difference. – leppie Dec 16 '10 at 08:16
  • possible duplicate of [Declare delegate manually, use Func or Action?](http://stackoverflow.com/questions/4482613/declare-delegate-manually-use-funct-or-actiont) – nawfal Dec 20 '13 at 07:31

5 Answers5

5

Func<> is useful when it's very clear what they're used for, and the number of inputs is small.

When the number of inputs is larger, or there could be some ambiguity over the intent - then using a delegate with named arguments makes things clearer.

  • if the number of inputs is larger, isn't it harder to remember them if it is called LotsOfInputFunction than, Func. And if the intent is not clear I can clarify it in variable name or parameter name instead, right? – Louis Rhys Dec 16 '10 at 07:52
  • 3
    I meant intent of each parameter. For instance: Func -- just looking at this it's hard/impossible to infer what it's for. In addition, adding a parameter can mean refactoring a significant amount of code, and potentially breaking interfaces. –  Dec 16 '10 at 09:24
1

They are for all purposes the same, except when the method has an Expression parameter. Those need to be defined as a 'lambda' and not delegate. This would be very problematic when dealing with IQueryable and getting the IEnumerable invoked/resolved instead (eg LINQ2SQL).

leppie
  • 115,091
  • 17
  • 196
  • 297
1

Func<> and Action<> are preferable if they are actually appropriate in your case. Runtime creates instances of every type used in your program, and if you use Func once it means that the instance of type was created. In case of custom delegate things go in different way and new types will be created even though they are essentially similar to existing.

However sometimes custom delegates make code clearer.

Tony Kh
  • 1,512
  • 11
  • 8
1

However I notice Microsoft uses its own delegate at some libraries, for example event handlers. So, what are the advantages and drawbacks of either of them? when should I use it?

Some of this is historic: APIs defined before C#3/.NET3 when Action<> and Func<> were added. For events EventHandler<T> is a better choice for events because it enforces the right convention.

Richard
  • 106,783
  • 21
  • 203
  • 265
  • [this](http://msdn.microsoft.com/en-us/library/system.activities.bookmarkcallback.aspx) is from .NET 4 – Louis Rhys Dec 16 '10 at 09:05
  • 1
    @Louis ... elsewhere in WF4 [`Func<>` is used](http://msdn.microsoft.com/en-us/library/system.activities.workflowapplication.onunhandledexception.aspx) so that's odd. One that slipped through the consistency review? – Richard Dec 16 '10 at 09:28
0

You can always create a class which holds the n number of input as class properties and pass the object of the class a single input in the func<> delegate

TalentTuner
  • 17,262
  • 5
  • 38
  • 63