Convert from Old delegate to Action/Func delegate

Lancis007 41 Reputation points
2021-09-08T19:03:09.533+00:00

Hi everybody, the below code is working fine, I'm busy learning delegates and I'm now learning Func and Action.

I just want to see how the multicast delegate works with Func and Action cause most of books I read about Action and Func doesn't use them in multicast way.

Because I noticed that Action and Func delegate doesn't work well in multicast, if you plug two or multiple methods, it only displays data from the last plugged method.
that's why I want to see how you guys going to achieve multicast with Action and Func using the below class.

You can also comment out all if statement inside the 3 methods to see how the old multicast delegate display all the 3 methods data but the doing the same thing with Action/Func seems like it's not possible.

Not sure, but let see how you're gonna achieve it.

Can you please assist me converting this below code from old delegate to Action, then Func delegate ?

I'm working on VS 2019, .Net Core.

namespace DelegateGreetingApp
{
    // 1. 
    delegate void GreetingDelegate();

    class Program
    {
        static void Main(string[] args)
        {
            GreetingDelegate greet = new GreetingDelegate(GoodMorning);
            greet += GoodAfternoon;
            greet += GoodEvening;

            greet();


            Console.Read();
        }

        static void GoodMorning()
        {
            //if (DateTime.Now.ToString().EndsWith("PM"))

            if (DateTime.Now.Hour > 4 && DateTime.Now.Hour < 12)
                Console.WriteLine("Good Morning");
        }

        static void GoodAfternoon()
        {
            //if (DateTime.Now.ToString().EndsWith("PM"))

            if(DateTime.Now.Hour > 11 && DateTime.Now.Hour < 17)
                Console.WriteLine("Good Afternoon");
        }

        static void GoodEvening()
        {
            if (DateTime.Now.Hour > 16 || DateTime.Now.Hour < 5)
                Console.WriteLine("Good Evening");
        }
    }
}

** Good Morning
* ------------
* 5:00 AM — 11:59 AM
*
*
* Good Afternoon
* --------------
* 12:00 PM — 4:59 PM
*
*
* Good Evening
* ------------
* 5:00 PM — 4:59 AM*

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,264 questions
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,077 questions
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,097 questions
0 comments No comments
{count} votes

Accepted answer
  1. P a u l 10,401 Reputation points
    2021-09-08T19:39:40.273+00:00

    I've simplified the implementation from the methods for brevity, but functionality-wise multicasting a delegate defined with the delegate keyword will be as intuitive as multicasting with the equivalent Action or Func type.

    One thing to note is that if your GreetingDelegate had a return value rather than void, making it functionally equivalent to a Func, multicasting isn't especially useful if your goal is to use the return value of each call. The default behaviour is that when you call "greetFunc" below it will execute each of the added functions in series, but the return value with be the value returned by the last function added to the multicast list, so "3".

    It is possible to loop through each function individually, although that does make multicasting somewhat pointless:

    foreach (Func<int> func in greetFunc.GetInvocationList()) {
        Console.WriteLine(func());
    }
    

    Updated source:

    using System;
    
    namespace DelegateGreetingApp {
        // 1. 
        delegate void GreetingDelegate();
    
        class Program {
            static void Main(string[] args) {
                // 1. Multicast delegates
                GreetingDelegate greetDelegate = new GreetingDelegate(GoodMorning);
                greetDelegate += GoodAfternoon;
                greetDelegate += GoodEvening;
                greetDelegate();
    
                Console.WriteLine("---");
    
                // 2. Multicast delegates (using Action)
                Action greetAction = GoodMorning;
                greetAction += GoodAfternoon;
                greetAction += GoodEvening;
                greetAction();
    
                Console.WriteLine("---");
    
                // 3. Multicast delegates (using Func)
                Func<int> greetFunc = () => {
                    GoodMorning();
                    return 1;
                };
                greetFunc += () => {
                    GoodAfternoon();
                    return 2;
                };
                greetFunc += () => {
                    GoodEvening();
                    return 3;
                };
                Console.WriteLine(greetFunc());
    
                Console.Read();
            }
    
            static void GoodMorning() {
                //if (DateTime.Now.ToString().EndsWith("PM"))
    
                if (DateTime.Now.Hour > 4 && DateTime.Now.Hour < 12)
                    Console.WriteLine("Good Morning");
            }
    
            static void GoodAfternoon() {
                //if (DateTime.Now.ToString().EndsWith("PM"))
    
                if (DateTime.Now.Hour > 11 && DateTime.Now.Hour < 17)
                    Console.WriteLine("Good Afternoon");
            }
    
            static void GoodEvening() {
                if (DateTime.Now.Hour > 16 || DateTime.Now.Hour < 5)
                    Console.WriteLine("Good Evening");
            }
        }
    }
    
    0 comments No comments

4 additional answers

Sort by: Most helpful
  1. Lancis007 41 Reputation points
    2021-09-08T20:08:45.753+00:00

    @P a u l Thanks for the code.

    But, in my above class, within each method there's a condition inside that check the current time and run a specific method accordingly. Your code only displays the all 3 methods directly without checking against the condition.

    I wanted a multicast Func and Action that run a specific method according to the current time. I updated my post to add the schedule.


  2. Lancis007 41 Reputation points
    2021-09-08T20:43:23.027+00:00

    I see the updated code. It's now working fine using Action. Thank you !!!

    So is this a good design or bad design ?

    If you had that requirement and were to design and write an application to show Morning/Afternoon/Evening according to the above time schedule using delegate Action or Func, how would you go write it?

    I just want to see how advanced developers think.

    I also read on C# Official doc that delegates promote Single Responsibility and Separation of Concern principle, so I decided to use it everywhere.


  3. Lancis007 41 Reputation points
    2021-09-08T22:28:26.68+00:00

    @P a u l Thanks, that's awesome and clean.

    Thank you so much Paul.


  4. Bruce (SqlWork.com) 53,426 Reputation points
    2021-09-09T15:36:58.457+00:00

    Action and Func are generic delegates. you could skip the delegate definition and just use an action:

         public class Program
         {
             static void Main(string[] args)
             {
                 Action greet = GoodMorning;
    
                 greet += GoodAfternoon;
                 greet += GoodEvening;
                 greet += () => {
                   Console.WriteLine("hello");
                 };
                 greet();
    
    
                 Console.Read();
             }
    
             ....
    }
    
    0 comments No comments