委托代码详解

博客 分享
0 192
张三
张三 2022-04-06 11:57:38
悬赏:0 积分 收藏

委托代码详解

C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。

委托(Delegate) 是存有对某个方法的引用的一种引用类型变量 。

现实世界中的委托:

自己动手模式:

image

委托模式:一种类型的委托

image

委托模式:多种类型的委托

image

一、C#内置委托

(1)Action委托:用于调用无参数,无返回值的函数。

class OASystem{    public void WelComeChinese()    {    	Console.WriteLine("您好,欢迎来到******系统!");    }    public void WelComeEnglish()    {    	Console.WriteLine("Hello, welcome to the ****** system!");    }}
static void Main(string[] args){    //直接调用    //OASystem oa = new OASystem();    //oa.WelComeChinese();    //oa.WelComeEnglish();    //委托调用    OASystem oa = new OASystem();    Action action1 = new Action(oa.WelComeChinese);    Action action2 = new Action(oa.WelComeEnglish);    action1();       //或action1.Invoke();    action2();      //或action2.Invoke();}

(2)Func委托:一种泛型委托,Func有一系列的重载。

class Calculator{    public int Add(int a, int b)    {    	return a + b;    }    public int Sub(int a, int b)    {    	return a - b;    }    public int Mul(int a, int b)    {    	return a * b;    }    public int Div(int a, int b)    {    	return a / b;    }}
static void Main(string[] args){    //直接调用任意一种运算    //Calculator cal = new Calculator();    //int result = cal.Add(1, 2);    //Console.WriteLine(result);    Calculator cal = new Calculator();    Func<int, int, int> func = new Func<int, int, int>(cal.Add);    int result = func(1, 2);     //或func.Invoke(1, 2);    Console.WriteLine(result);}

(3)Predicate:一个传入参数,返回值为bool。

class MyDate{    //判断年份是否是闰年    public bool Is29(int year)    {        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)        	return true;        else        	return false;    }    //判断是否需要工作(星期一到星期五需要工作,周六周日不需要)    public bool IsWork(DateTime date)    {        if ((int)date.DayOfWeek == 0 || (int)date.DayOfWeek == 6)        	return false;        else        	return true;    }}
static void Main(string[] args){    //直接调用两个方法    //bool result = false;    //MyDate myDate = new MyDate();    //result = myDate.Is29(2020);    //Console.WriteLine("闰年:"+result);    //result = myDate.IsWork(new DateTime(2020, 7, 3));    //Console.WriteLine("工作:"+result);    //委托调用两个方法    bool result = false;    MyDate myDate = new MyDate();    Predicate<int> pre1 = new Predicate<int>(myDate.Is29);    result = pre1(2020); //或result = pre1.Invoke(2020);    Console.WriteLine("闰年:" + result);    Predicate<DateTime> pre2 = new Predicate<DateTime>(myDate.IsWork);    result = pre2(new DateTime(2020, 7, 3)); //或result = pre2.Invoke(new DateTime(2020, 7, 3));    Console.WriteLine("工作:" + result);}

二、自定义委托及委托的多播(组播)

class Calculator{    public int Num { get; set; }    public void Add(int n)    {    	this.Num += n;    }    public void Sub(int n)    {    	this.Num -= n;    }    public void Mul(int n)    {    	this.Num *= n;    }    public void Div(int n)    {    	this.Num /= n;    }}
delegate void ChangeNum(int n);class Program{    static void Main(string[] args)    {        //自定义委托调用函数方法        //Calculator cal = new Calculator();        //cal.Num = 100;        //ChangeNum cnAdd = new ChangeNum(cal.Add);        //cnAdd(10);        //Console.WriteLine(cal.Num);        //委托的多播(组播)        //相同类型的委托被合并,可以创建一个委托被调用时要调用的方法的调用列表        Calculator cal = new Calculator();        cal.Num = 100;        ChangeNum cnAdd = new ChangeNum(cal.Add);        ChangeNum cnSub = new ChangeNum(cal.Sub);        ChangeNum cnMul = new ChangeNum(cal.Mul);        ChangeNum cnDiv = new ChangeNum(cal.Div);        ChangeNum cn = cnAdd;        cn += cnMul;        cn += cnSub;        cn(50);        Console.WriteLine(cal.Num);    }}

三、委托作为参数传递

手机类:

class Phone  //手机{	public string Name { get; set; }  //手机名字}

包装盒类:

class Box  //包装盒{	public Phone MyPhone { get; set; } //手机}

手机生产工厂类:

class PhoneFactory{    public Phone MakeXiaoMi()    {        Phone phone = new Phone();        phone.Name = "小米手机";        return phone;    }    public Phone MakeHuawei()    {        Phone phone = new Phone();        phone.Name = "华为手机";        return phone;    }}

包装生产工厂类:

delegate Phone MakePhone();class WrapFactory{    #region 为每种手机进行包装盒工作-常规写法    //包装小米手机    public Box WarpXiaoMi()    {        PhoneFactory phoneFactory = new PhoneFactory();        Phone phone = phoneFactory.MakeXiaoMi();        Box box = new Box();        box.MyPhone = phone;        return box;    }    //包装华为手机    public Box WarpHuawei()    {        PhoneFactory phoneFactory = new PhoneFactory();        Phone phone = phoneFactory.MakeHuawei();        Box box = new Box();        box.MyPhone = phone;        return box;    }    #endregion    #region 将委托作为参数    public Box WarpPhone(MakePhone mp)    {        Phone phone = mp();        Box box = new Box();        box.MyPhone = phone;        return box;    }    #endregion}

Main函数:

static void Main(string[] args){    #region 生产并包装两个手机-常规写法    //WrapFactory wrapFactory = new WrapFactory();    //Box box1 = wrapFactory.WarpXiaoMi();    //Console.WriteLine(box1.MyPhone.Name + "生产及包装已经完成!");    //Box box2 = wrapFactory.WarpHuawei();    //Console.WriteLine(box2.MyPhone.Name + "生产及包装已经完成!");    #endregion    #region 生产并包装两个手机-委托作为参数    PhoneFactory phoneFactory = new PhoneFactory();    MakePhone makeXiaomi = new MakePhone(phoneFactory.MakeXiaoMi);    MakePhone makeHuawei = new MakePhone(phoneFactory.MakeHuawei);    WrapFactory wrapFactory = new WrapFactory();    Box box1 = wrapFactory.WarpPhone(makeXiaomi);    Console.WriteLine(box1.MyPhone.Name + "生产及包装已经完成!");    Box box2 = wrapFactory.WarpPhone(makeHuawei);    Console.WriteLine(box2.MyPhone.Name + "生产及包装已经完成!");    #endregion}

四、利用委托实现匿名函数回调

delegate void CallBackDelegate(int score);class Student{    public string Name { get; set; } //姓名    public string Mail { get; set; } //邮箱    public int Score { get; set; } //分数    public void Exam(CallBackDelegate callback = null)    {        Console.WriteLine("请填写姓名:");        this.Name = Console.ReadLine();        Console.WriteLine("请填写邮箱:");        this.Mail = Console.ReadLine();        Random rnd = new Random();        this.Score = rnd.Next(0, 101);        Console.WriteLine("该学生面试成绩为:" + this.Score);        if (callback != null)        callback(this.Score);    }}
static void Main(string[] args){    //Student stu = new Student();    //CallBackDelegate myDelegate = delegate (int score)    //{    //    if (score >= 60)    //        Console.WriteLine("已经给" + stu.Name + "的邮箱:"    //            + stu.Mail + "发送了录用入职邀请!");    //    else    //        Console.WriteLine("很遗憾,我们不能录用您!");    //};    //stu.Exam();   //无参数调用    //stu.Exam(myDelegate);  //有参数调用    Student stu = new Student();    //stu.Exam();    //或    stu.Exam((score) =>    {        if (score >= 60)        	Console.WriteLine("已经给" + stu.Name + "的邮箱:" +         		stu.Mail + "发送了录用入职邀请!");        else        	Console.WriteLine("很遗憾,我们不能录用您!");    });}

五、委托与事件

class EventTest{    public delegate void MyEventHandler();    public event MyEventHandler ValueChanged;    private int value;    public int Value    {        get        {        	return value;        }        set        {            ValueChanged();            this.value = value;        }    }}
static void Main(string[] args){       EventTest et = new EventTest();    et.ValueChanged += new EventTest.MyEventHandler(myEventFunction);    et.Value = 100;    et.Value = 200;}public static void  myEventFunction(){	Console.WriteLine("value值在发生改变!");}
posted @ 2022-04-06 11:19 農碼一生 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    张三

    张三 (王者 段位)

    821 积分 (2)粉丝 (41)源码

     

    温馨提示

    亦奇源码

    最新会员