Func, Action, Predicate delegates, events in C#

Noah Aas 240 Reputation points
2024-05-09T19:00:01.6066667+00:00

Hello!

I am looking for a good short guide on when and how to take what.

Do you have any examples or do you know a good site?

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,357 questions
{count} votes

Accepted answer
  1. Bruce (SqlWork.com) 57,646 Reputation points
    2024-05-09T21:23:56.89+00:00

    the ability to create a callback method is common. C# is a typed language, so in order to define typed callback (return and parameter types), you create a delegate. so the result of defining a delegate is new type of delegate.

    delegate bool IsValid(string s); // define a new type of callback that 
                                     //   returns bool and take a string parameter
    ...
    
    IsValid callback;   // define a variable of delegate type IsValid
    callback = s => s?.Length > 1;   // using lambda, define a callback function
    
    var result = callback("test");   // invoke the callback code
    
    

    delegates are so handy, that when when generic were added, were created generic delegates where created so the delegate type need not be predefined:

    • Action<> a void delegate of parameter types
    • Func<> a delegate of parameters types and a return type
    • Predicate<> a delegate of parameters types and a return type of bool
    Action<string> callback = s => Console.WriteLine(s); 
    callback("test");
    
    Func<string,bool> isvalid = s => s.Length > 10;
    bool result = isvalid("test");
    
    Predicate<string> isvalid2 = s => s.Length > 10;
    bool result2 = isvalid2("test");
    

    an event is a collection of delegates. generally they are defined as void, as you can not access the return value;

    delegate void StringHandler (string s); // define delegate
    event StringHandler callbacks;      // define event variable of type StringHandler
    ...
    
    callbacks += s => Console.WriteLine(s);  // add a callback 
    callbacks += s => Console.WriteLine(s);  // add another
    callbacks.Invoke("test");  // writes "test" twice to console
    
    

1 additional answer

Sort by: Most helpful
  1. P a u l 10,406 Reputation points
    2024-05-09T19:38:07.7266667+00:00

    This article seems reasonable:

    https://medium.com/nerd-for-tech/c-delegates-actions-events-summary-please-8fab0244a40a

    The TLDR is that Func<T>, Action & delegates declared via the delegate keyword are for most intents and purposes the same. The delegate format came first and Func and Action came in later .NET versions.

    The main benefit of the delegate keyword variant is that you can apply keywords to them (as you would with a regular method signature) such as params, in, out & ref. E.g. you could express a "string-to-int" parsing function like this with a delegate:

    delegate bool TryParseInt(string value, out int value);
    

    But not with the equivalent Func<T>:

    Func<string, out int, bool> Delegate; // <-- Won't compile!
    

    An event is something that you subscribe to (i.e. you register your delegate, in which format of delegate above you prefer). When the event is invoked, your delegate will be called. The benefit of an using an event instead of straight delegate is that you can register/un-register as many delegates to a single event as you want.