赵星汉同学的技术博客 Software testing & software engineering

学习C#委托的笔记

2021-07-28
Frank Xinghan Zhao


最近在看C#,以前学习VC的时候没有委托的概念,用的都是回调函数,现在正好学习一下。

概念

和回调差不多,都是在对象或者过程中定义一个类似的“接口”,然后在后边写清楚这个接口的具体实现。但是委托的功能回调函数强大太多了。

实现方法

1)在类的定义里,首先定义一个公开的委托类型。

public delegate void XXXHandler(XXX XXXX);

2)定义每个委托类型的成员变量。

private XXXHandler listOfHandler;

3)向调用者添加注册函数

public void RegisterXXXX(XXXHandler methodToCall)
{
    listOfHandler += methodToCall;
}

4) 在需要用的时候,new一个XXXHandler对象,并将处理的函数作为参数指定给该对象

xx.RegisterXXXX(new xx.XXXHandler(XXXXEvent)) //这里XXXEvent是定义在外部的处理函数

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace test3
{
    public class Car
    {
        public int CurrentSpeed { get; set; }
        public int MaxSpeed { get; set; }
        public string PetName{ get; set; }

        private bool carIsDead;

        public Car() { MaxSpeed = 100; }
        public Car( string name, int maxSp, int currSp)
        {
            CurrentSpeed = currSp;
            MaxSpeed = maxSp;
            PetName = name;
        }

        public delegate void CarEngineHandler(string msgForCaller);

        private CarEngineHandler listOfHandlers;

        public void RegisterWithCarEngine(CarEngineHandler methodToCall)
        {
            listOfHandlers += methodToCall; //用+=就可以支持多路的广播了,而不是用=, Remove:-=
        }

        public void UnRegisterWithCarEngine(CarEngineHandler methodToCall)
        {
            listOfHandlers -= methodToCall;
        }

        public void Accelerate(int delta)
        {
            if (carIsDead)
            {
                if (listOfHandlers != null)
                {
                    listOfHandlers("Sorry, this car is dead ...");
                }
            }
            else
            {
                CurrentSpeed += delta;

                if (10 == (MaxSpeed - CurrentSpeed) && listOfHandlers != null)
                {
                    listOfHandlers("Careful buddy! Gonna blow!");
                }

                if (CurrentSpeed >= MaxSpeed)
                    carIsDead = true;
                else
                    Console.WriteLine("CurrentSpeed = {0}", CurrentSpeed);
            }
            
        }
    }
  
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("****  Delegates as event enablers ******\n");

            Car c1 = new Car("SlugBug", 100, 10);

            Car.CarEngineHandler handler1 = new Car.CarEngineHandler(OnCarEngineEvent);
            c1.RegisterWithCarEngine(handler1);
            Car.CarEngineHandler handler2 = new Car.CarEngineHandler(OnCarEngineEvent2);
            c1.RegisterWithCarEngine(handler2);

            Console.WriteLine("**** Speeding up *****");

            for(int i = 0; i< 6;i ++)
            {
                c1.Accelerate(20);
            }
            Console.ReadLine();

            c1.UnRegisterWithCarEngine(handler2);

            Console.WriteLine("****** Speeding up*******");
            for(int i  = 0; i<6; i++)
            {
                c1.Accelerate(20);
            }

            Console.ReadLine();
        }

        public static void OnCarEngineEvent(string msg)
        {
            Console.WriteLine("\n ******** Message From Car Object *********");
            Console.WriteLine(" => {0}", msg);
            Console.WriteLine("******************\n");
        }

        public static void OnCarEngineEvent2(string msg)
        {
            Console.WriteLine("=>{0}", msg.ToUpper());

        }
    }
}

其他

委托不仅支持多路广播(通过+=),还支持泛型,因暂时用不着,用到的时候再看吧。


下一篇 C#里的事件

Comments

Content