委托

定义: 委托是一种引用类型, 是对特定参数列表和返回类型方法的引用.

使用方法: 

1. 委托作为参数传入其他方法(作为回调函数), 实现类的解耦

2. 实现事件处理

举例:

1. 作为参数传入其他方法 , 可用于解耦

namespace 回调函数
{
    /*
    * 目的: 熟悉委托的使用(作为回调函数)
    * 好处: Me与Daughter解耦, Me做晚饭并不依赖于特定的人买酱油
    */
    internal class Program
    {
        static void Main(string[] args)
        {
            Me me = new Me();
            Daughter daughter = new Daughter();

            me.MakeDinner(daughter.BuySoySauce); // 好吧, 女儿去买酱油
        }
    }

    internal class Me
    {
        // 委托他人买酱油
        internal delegate SoySauce BuySoySauceDelegate();

        // 做晚饭
        internal void MakeDinner(BuySoySauceDelegate buySoySauce)
        {
            var soySauce = buySoySauce();
            Cook(soySauce);

            Console.WriteLine("I: Dinner already done , enjoy it");
        }

        // 烹饪
        internal void Cook(SoySauce soySauce)
        {
            Console.WriteLine("I: Cook the dinner...");
            Console.WriteLine("I: Cook done");
        }
    }

    internal class Daughter
    {
        // 买酱油
        internal SoySauce BuySoySauce()
        {
            Console.WriteLine("Daughter: Give me 100 yuan");
            Thread.Sleep(3000);
            Console.WriteLine("Daughter: This your soy sauce");
            return new SoySauce();
        }
    }

    class SoySauce
    {
        public string Name => "Soy Sauce";  // 酱油
    }
}
View Code

该例子中, 我做饭的流程其实并不依赖女儿买酱油 ( 我并不依赖女儿买酱油, 否则女儿不在家也做不了饭, 我可以让任意家人帮我买酱油, 所以通过委托实现了我与女儿的解耦)

2. 用于实现事件处理

namespace 实现事件处理
{
    /*
     * 目的: 使用委托实现事件处理
     * 好处: 只要订阅Me的OnLog方法, 即可记录Me的Log, 在Me类中不需要实现Logger类
     */
    internal class Program
    {
        static void Main(string[] args)
        {
            Me me = new Me();
            me.OnLog += OnLog;

            // 开始我的一天
            me.StartMyNewDay();

            me.OnLog -= OnLog;
        }

        private static void OnLog(object sender, EventArgs e)
        {
            Console.WriteLine(e.ToString());
        }
    }


    internal class Me
    {
        internal delegate void LogHandler(object sender, LogArgs e);
        internal event LogHandler OnLog;

        internal void StartMyNewDay()
        {
            // 起床
            Log("I wake up, it's a new day");
            Thread.Sleep(500);

            // 吃早饭
            Log("Have breakfast, not bad");
            Thread.Sleep(500);

            // 开车去上班
            Log("Drive to the company");
            Thread.Sleep(500);

            // 上班
            Log("Do the work");
            Thread.Sleep(500);

            // 吃午饭
            Log("Have the lunch now");
            Thread.Sleep(500);

            // 继续上班
            Log("Have a lot of work to do");
            Thread.Sleep(500);

            // 开车下班
            Log("It's time to go home!");
            Thread.Sleep(500);

            // 吃晚饭
            Log("Enjoy the dinner :)");
            Thread.Sleep(500);

            // 睡觉
            Log("Go to sleep...");
            Thread.Sleep(500);

        }

        private void Log(string message)
        {
            OnLog.Invoke(this, new LogArgs(message));
        }

        internal class LogArgs : EventArgs
        {
            public LogArgs(string textMessage)
            {
                this.textMessage = textMessage;
            }

            private string textMessage { get; set; }

            public override string ToString()
            {
                return textMessage;
            }
        }
    }
}
View Code

该例子中, 在Me类中不需要实现Logger类, 将Log以事件的形式通知Log, 谁想记录该Log就去订阅该事件

posted @ 2023-11-30 07:15  勇生  阅读(7)  评论(0)    收藏  举报