Understanding C# Delegation (Delegate) is easy to understand and explains in simple terms

What is a commission?

A delegate is first of all a data type. We can define a delegate type just like a structure. A delegate (Delegate) is a reference type variable that holds a reference to a method. References can be changed at runtime

Definition of delegation

//语法
delegate <return type> <delegate-name> <parameter list>
//实例
public delegate int MyDelegate (string s);

Instantiate the delegate (Delegate)

For example:

public delegate void printString(string s);
...
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);

To put it bluntly, it is similar to a pointer to a function method. We can define the type of the delegate just like defining the pointer type.

When defining a delegate type, you must specify the parameter type and return value of the function. Once the delegate type is declared, the delegate object must be created using the new keyword and is related to a specific method. When creating a delegate, the parameters passed to the new statement are written like a method call, but without parameters.

Simple usage example

using System;

delegate int NumberChanger(int n);
namespace DelegateAppl
{
    
    
   class TestDelegate
   {
    
    
      static int num = 10;
      public static int AddNum(int p)
      {
    
    
         num += p;
         return num;
      }

      public static int MultNum(int q)
      {
    
    
         num *= q;
         return num;
      }
      public static int getNum()
      {
    
    
         return num;
      }

      static void Main(string[] args)
      {
    
    
         // 创建委托实例
         NumberChanger nc1 = new NumberChanger(AddNum);
         NumberChanger nc2 = new NumberChanger(MultNum);
         // 使用委托对象调用方法
         nc1(25);
         Console.WriteLine("Value of Num: {0}", getNum());
         nc2(5);
         Console.WriteLine("Value of Num: {0}", getNum());
         Console.ReadKey();
      }
   }
}

This is just a simple usage introduction. It can be seen that this is no different from calling the method directly in the main program, and it is not the actual usage.

Purpose of delegation

multicast

Delegate objects can be combined using the "+" operator. A merged delegate calls the two delegates it merges. Only delegates of the same type can be merged. The "-" operator can be used to remove component delegates from merged delegates.

Using this useful feature of delegates, you can create a call list of methods to be called when the delegate is called. This is called delegated multicasting, also called multicast. The following program demonstrates delegated multicasting

static void Main(string[] args)
      {
    
    
         // 创建委托实例
         NumberChanger nc;
         NumberChanger nc1 = new NumberChanger(AddNum);
         NumberChanger nc2 = new NumberChanger(MultNum);
         nc = nc1;
         nc += nc2;
         // 调用多播
         nc(5);
         Console.WriteLine("Value of Num: {0}", getNum());
         Console.ReadKey();
      }
   }
}

Key: usage scenarios of delegation

Delegation, hence the name, lets use a vivid metaphor. In the company, the boss/caller does not need to entrust me/activate the delegation function, but can personally arrange work for Zhang San/func1 and Li Si/func2, that is, directly call, At this time, you may need to prepare the parameters of the call and the code of the calling method, such as a loop call.
The boss/caller can also arrange the work of Zhang San and Li Si through the function of my/activation delegation. At the same time, you can also specify Zhang San/func1 and Li Si/func2 together. Work/ ±Multicast can also be expanded with new employees/methods.
It is similar to class inheritance polymorphism, but more flexible. I/activate the delegate function does not need to know what function it wants to call and its specific implementation. It just needs to use the parameters given by the caller. The parent class does not need to worry about how the subclass implements it. , through assignment of subtypes, methods overridden by subclasses can be called.


        //委托

        // 委托声明
        public delegate void doSomething(string s);
		//定义 回调函数  ,公司里的员工 张三,李四.............
		public static void ZangSan(string a) {
    
    
			Console.WriteLine("zhangsan"+a);
		}
        public static void LiSi(string a)
        {
    
    
            Console.WriteLine("lisi"+a);
        }
        /// <summary>
        /// 中介,委托处理 ,使用此方法触发委托回调
        /// </summary>
        /// <param name="from">开始</param>
        /// <param name="to">结束</param>
        /// <param name="fb">委托引用</param>      
            private static void handleDelegate(int from, int to, doSomething ds)
            {
    
    
			//一些预处理 ,这样使用委托就比直接调用方便了
                for (int val = from; val <= to; val++)
                {
    
    
                 
                    if (ds != null)
                    {
    
    
                        ds(val.ToString());
                    }
                    //ds?.Invoke(val); 简化版本调用
                }
            }
        

        //主函数,调用者 老板
        public void testDelegate()
        {
    
         //老板通过我/中介 给张三安排工作,
			doSomething dsZhangSan = new doSomething(ZangSan);
			//给张三李四 按顺序安排工作  //按序执行
			doSomething dsLisi = new doSomething(LiSi);
			doSomething ds = dsZhangSan + dsLisi;
			//在调用的时可以给张三,李四传参数,这里在handleDelegate里面给了 ds(val.ToString());
			handleDelegate(0, 3, ds);

			//方法的返回值,参数必须完全一样,符合委托类型的定义
		}

execution structure

Insert image description here

The mechanism of callback function

Think of me as an independent intermediary that provides services, and the boss/the party implementing the function, Zhang San/func1, Li Si/func2 ~~~ are from the same company. When we cooperate, the boss designates Zhang San or Li Si... , And I don't need to care, I just call Zhang San and Li Si when the special conditions occur.

⑴定义一个回调函数;
⑵提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者;
⑶当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。

Guess you like

Origin blog.csdn.net/qq_43886548/article/details/127882628