C# 委托

1. 委托定义

  • 委托(delegate)是函数指针的升级版。委托是将方法作为方法的参数。

  • 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来传递。

  • 一切皆地址。

    • 变量(数据)是以某个地址为起点的一段内存中所存储的值;
    • 函数(算法)是以某个地址为起点的一段内存中所存储的一组机器语言指令。
  • 直接调用与间接调用

    • 直接调用:通过函数名来调用函数,CPU通过函数名直接获得函数所在地址并开始执行,返回;
    • 间接调用:通过函数指针来调用函数,CPU通过读取函数指针存储的值获得函数所在地址并开始执行,返回。
  • 委托的声明原型:
    delegate <函数返回类型><委托名>(<函数参数>)
    public delegate void MyDelegate(string s);
    委托MyDelegate可以被用于引用任何一个有单一string类型参数的方法,并返回void类型变量。

namespace Ex20210411_1
{
    //委托:把方法作为方法的参数
    public delegate void GreetingDelegate(string name);
    class Program
    {
        private static void EnglishGreeting(string name)
        {
            Console.WriteLine("Hello," + name);
        }
        private static void ChineseGreeting(string name)
        {
            Console.WriteLine("你好," + name);
        }
        private static void SayHello(string name,GreetingDelegate GreetPeople)
        {
            GreetPeople(name);
        }
        static void Main(string[] args)
        {
            SayHello("Tom", EnglishGreeting);
            SayHello("Mike", ChineseGreeting);
            //间接调用委托
            GreetingDelegate g1 = new GreetingDelegate(ChineseGreeting);//实例化委托
            GreetingDelegate g2 = ChineseGreeting;
            g1("张三");
            //直接调用委托
            EnglishGreeting("Lily");           
        }
    }
}

2. 实例化委托

  • 委托对象可以通过使用new关键字来创建,且与一个特定的方法有关。
  • 当创建委托时,传递到new语句的参数就像方法调用一样书写,但是不带有参数。
  • 委托是函数指针的“升级版”。

3. 内置委托

  • Action是无返回值的泛型委托
    • Action表示无参,无返回值的委托;
    • Action<int,string> 表示有传入参数int,string,无返回值的委托;
    • Action<int,string,bool> 表示有传入参数int,string,bool,无返回值的委托;
    • Action<int,int,int,int> 表示有传入4个int型参数,无返回值的委托;
    • Action至少0个参数,至多16个参数,无返回值。
  • Func是有返回值的泛型委托
    • Func 表示无参,返回值为int的委托;
    • Func<object,string,int> 表示传入参数为object,string, 返回值为int的委托;
    • Func<T1,T2,T3,int> 表示传入参数为T1,T2,T3,(泛型)返回值为int的委托;
    • Func 至少有0个参数,至多16个参数,根据返回值泛型返回。必须有返回值,不可void.
//内置委托
namespace Ex20210411_2
{
    class Program
    {
        static void Main(string[] args)
        {
            Greeting g1 = new Greeting();

            Action action1 = new Action(g1.SayHelloEveryone);
            Action<string> action2 = new Action<string>(g1.SayHello);
            action1();
            action2("Lily");

            Caculate c1 = new Caculate();
            Func<int, int, int> f1 = new Func<int, int, int>(c1.Add);
            Func<int, int, int> f2 = new Func<int, int, int>(c1.Sub);
            Console.WriteLine(f1(100, 200));
            Console.WriteLine(f2(100, 200));           
        }
    }
    class Greeting
    {
        public void SayHelloEveryone()
        {
            Console.WriteLine("Hello,everyone.");
        }
        public void SayHello(string name)
        {
            Console.WriteLine("Hello," + name);
        }
    }
    class Caculate
    {
        public int Add(int x, int y)
        {
            return x + y;
        }
        public int Sub(int x,int y)
        {
            return x - y;
        }
    }
}

4. 多播委托

  • 委托对象可使用“➕”运算进行合并,当然也可以使用“➖”运算从合并的委托中移除组件委托;
  • 只有相同类型的委托可以被合并;
  • 调用多播委托时,方法按照添加的顺序被依次调用。
//多播委托
/*
委托对象可使用"+"运算符进行合并
"-"运算符可用于从合并的委托中移除组件委托。
只有相同类型的委托可被合并。
调用多播委托时,方法将按照添加的顺序被依次调用。*/
namespace Ex20210411_3
{
    class Program
    {
        static void Main(string[] args)
        {
            Draw d1 = new Draw() { StuID = 1, PenColor = ConsoleColor.Red };
            Draw d2 = new Draw() { StuID = 2, PenColor = ConsoleColor.Green };
            Draw d3 = new Draw() { StuID = 3, PenColor = ConsoleColor.Blue };

            Action action1 = new Action(d1.DrawPictrue);
            Action action2 = new Action(d2.DrawPictrue);
            Action action3 = new Action(d3.DrawPictrue);

            action1 += action2;
            action1 += action3;

            action1();

            action1 -= action3;
            action1();
            //action2();
            //action3();
        }
    }
    class Draw
    {
        public int StuID { get; set; }
        public ConsoleColor PenColor { get; set; }
        public void DrawPictrue()
        {
            Console.ForegroundColor = PenColor;
            Console.WriteLine("Student{0} draw a cat.", StuID);
            Console.WriteLine("Student{0} draw a dog.", StuID);
        }
    }
}

5. 隐式异步调用和显示异步调用 Task / BeginInvoke

    class Program
    {
        static void Main(string[] args)
        {
            Student stu1 = new Student() { ID = 1, PenColor = ConsoleColor.Red };
            Student stu2 = new Student() { ID = 1, PenColor = ConsoleColor.Green };
            Student stu3 = new Student() { ID = 1, PenColor = ConsoleColor.Blue };

            Action action1 = new Action(stu1.doHomework);
            Action action2 = new Action(stu2.doHomework);
            Action action3 = new Action(stu3.doHomework);         
            action1.BeginInvoke(null, null);
            action2.BeginInvoke(null, null);
            action3.BeginInvoke(null, null);
            
            Task task1 = new Task(new Action(stu1.doHomework));
            Task task2 = new Task(new Action(stu2.doHomework));
            Task task3 = new Task(new Action(stu3.doHomework));
            task1.Start();
            task2.Start();
            task3.Start();

            for (int i = 0; i < 10; i++)
            {
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("main thread");
                Thread.Sleep(1000);
            }
        }
    }

    class Student
    {
        public int ID { get; set; }
        public ConsoleColor PenColor { get; set; }
        public void doHomework()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.ForegroundColor = PenColor;
                Console.WriteLine("{0} do work {1} hour(s)", ID, i + 1);
                Thread.Sleep(1000);
            }
        }
    }

6. 相关代码下载地址

链接:https://pan.baidu.com/s/19C_qxIT5uX7YAsmDU9Qckg
提取码:tnni

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MechMaster

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值