C#基础-委托(Delegate)

委托:顾名思义,托别人帮你办事。

委托(Delegate)特别用于实现事件和回调方法。

举个基本例子:

小姐姐: Hello, 托你帮我修个东西呗? (声明委托类型)

我:  Hi,你要修啥呢?

小姐姐:修电脑、手机、电灯、马桶,我没有工具弄不了。。。。(委托类型实例化,并传入方法参数

我:ok,我马上带着工具过来搞定。 (实现委托的方法

来小姐姐家后,5分钟就修好了电脑。(委托实例运行了方法

10分钟后又修好了手机。 (给委托继续追加方法

用vs新建一个 C# 控制台文件.

1. 声明一个委托类型

namespace fixgirl

public class GoodGirl
{
    public delegate void FixGirlEventHandler();
    
}

2. 委托类型实例化,传入方法参数

namespace fixgirl

public class GoodGirl
{
    public delegate void FixGirlEventHandler();
    
    public static void Main(string[] args)
    {
        FixGirlEventHandler myDelegate = new FixGirlEventHandler(BadGuy.FixPC);
        myDelegate();
        Console.ReadKey();
    }
}

3. 实现委托的方法

 public class BadGuy
    {
        public static void FixPC()
        {
            Console.WriteLine("用工具修好了电脑");
        }
    }
 

4. 给委托继续追加方法

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

namespace fixgirl
{

    public class GoodGirl
    {
        public delegate void FixGirlEventHandler();

        public static void Main(string[] args)
        {
            FixGirlEventHandler myDelegate = new FixGirlEventHandler(BadGuy.FixPC);
            myDelegate += BadGuy.FixPhone;
            myDelegate();
            Console.ReadKey();
        }
    }

    public class BadGuy
    {
        public static void FixPC()
        {
            Console.WriteLine("用工具5分钟修好了电脑");
        }

        public static void FixPhone()
        {
            Console.WriteLine("用工具10分钟修好了手机");
        }
    }

委托用的最多的场景是回调方法。

委托是C#实现回调函数的一种机制。可能有人会问了,回调函数是个啥???

举个回调例子:

我是公司老板,公司现在正在进行招聘程序员和新员工入职培训,我委托一个HR小姐姐专门负责这两块工作,告诉这个小姐姐,一旦收到新的简历就转发给我一份,另外员工一旦应聘通过就进行入职培训,我委托小姐姐要做的工作:给我转发一份简历和进行入职培训(回调函数里的操作),就是回调函数的作用。

一旦有了满足条件(收到新简历),小姐姐就会转发给我(触发回调函数),

一旦有了满足条件(应聘通过), 小姐姐就会进行培训(触发回调函数)。

委托 printString 可用于引用带有一个字符串作为输入的方法,并不返回任何东西。

我们使用这个委托来调用两个方法,第一个把字符串打印到控制台,第二个把字符串打印到文件:

using System;
using System.IO;

namespace DelegateAppl
{
   class PrintString
   {
      static FileStream fs;
      static StreamWriter sw;
      // 委托声明
      public delegate void printString(string s);

      // 该方法打印到控制台
      public static void WriteToScreen(string str)
      {
         Console.WriteLine("The String is: {0}", str);
      }
      // 该方法打印到文件
      public static void WriteToFile(string s)
      {
         fs = new FileStream("c:\\message.txt", FileMode.Append, FileAccess.Write);
         sw = new StreamWriter(fs);
         sw.WriteLine(s);
         sw.Flush();
         sw.Close();
         fs.Close();
      }
      // 该方法把委托作为参数,并使用它调用方法
      public static void sendString(printString ps)
      {
         ps("Hello World");
      }
      static void Main(string[] args)
      {
         printString ps1 = new printString(WriteToScreen);
         printString ps2 = new printString(WriteToFile);
         sendString(ps1);
         sendString(ps2);
         Console.ReadKey();
      }
   }
}

设计模式中的观察者模式。
被观察对象中维护了一个观察者列表,这些观察者会对被观察者某个“动作”,即事件,做出各自不同的反映。
常见的例子如下:
某一场景下有主人,猫,狗3个对象。
当主人“打开门”后,猫“跑开了”,狗“叫了”。
整个过程中,主人就是被观察对象,猫和狗都是观察者。
一旦主人触发“打开门”这个事件的话,猫狗做出不同的反映,猫“跑开了”,狗“叫了”

总结:

委托从字面上理解就是一种代理,类似于房屋中介,由租房人委托中介为其租赁房屋。

在 C# 语言中,委托则委托某个方法来实现具体的功能。

委托是一种引用类型,虽然在定义委托时与方法有些相似,但不能将其称为方法。

委托在使用时遵循三步走的原则,即定义声明委托、实例化委托以及调用委托。

数据结构来讲,委托是和类一样是一种用户自定义类型。

委托是方法的抽象,它存储的就是一系列具有相同签名和返回回类型的方法的地址。

调用委托的时候,委托包含的所有方法将被执行。

委托是 C# 语言中的一个特色,通常将委托分为命名方法委托、多播委托、匿名委托,其中命名方法委托是使用最多的一种委托。

委托就是我们把一批具有相同特征的方法,通过建立与具有同样相同特征的委托的一个实例来进行传递,以使其它地方能对这些方法进行调用。即把方法当作参数进行传递

事件委托的好处是,别人给你开放入口,具体实现自己定义。

通过理解Button.Click事件的整个过程就会明白委托和事件了,不过得看下自定义控件,页面生命周期,回发,观察者模式,假以时日,委托和事件也就会一点点明白了。
ASP.NET WEBFORM中很多用到事件的地方,看看还是有帮助的。
很多ASP.NET程序员,觉得拖控件被人家看不起,还没弄懂委托和事件,就直接转MVC,有点可惜

委托就是对一个方法映射,把方法名当参数来传递,类似JS中的在某个function的参数中把另一个function的名称当参数来传递。

1. C#的委托等同于C++的函数指针 。可以 从 C++函数指针反过来理解C#委托。
2. 委托应用于“同步调用”的场景,如一个有声阅读器,打开记事本(1)并开始阅读(2),这是两个方法,但这时,我想
调用打开的方法时,同时调阅读,这时候委托就来了,把阅读这个方法作为参数传给“打开记事本”的方法。

微软提供了Action和Fun。。。其实基本上已经没必要自己写委托了

委托的主要好处是可以把方法作为参数/属性来赋值或传递。事件是委托的一种具体应用。委托可以理解为一种接口,具体的方法实现这个接口,在开发阶段只需要关心委托的定义就可以调用,而不用关心它如何实现的或者在哪里实现的。

参考链接:

https://blog.csdn.net/wnvalentin/article/details/81840339

https://www.cnblogs.com/jixiaosa/p/10687068.html

https://www.cnblogs.com/qcst123/p/11575557.html

http://c.biancheng.net/view/2932.html

https://blog.csdn.net/weixin_34072458/article/details/85652130

https://www.cnblogs.com/stwyhm/archive/2006/08/11/474235.html

https://bbs.csdn.net/topics/390751609/

发布了85 篇原创文章 · 获赞 30 · 访问量 27万+

猜你喜欢

转载自blog.csdn.net/qq_42672770/article/details/104431161