栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

C# 委托、事件

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C# 委托、事件

1.委托初始体验

委托是一个引用类型,其实它是一个类,保存方法的指针,它指向一个方法,当我们调用 委托的时候这个方法就立即被执行

using System;

namespace AdvancedDelegate
{
    //公共委托 与方法类似
    delegate void HelloDelegate(string msg);//定义委托
    internal class Program
    {
        static void Main(string[] args)
        {
            //把方法,放进委托里面,给定参数进行调用方法
            HelloDelegate helloDelegate = new HelloDelegate(Hello);//创建委托实列//委托指向的是一个方法
            helloDelegate("你好委托!");//给委托传输字符串
            helloDelegate.Invoke("你好委托!");
            Console.ReadKey();
        }
        public static void Hello(string str)//在静态类中调用,定义为static
        {
            Console.WriteLine(str);
        }
    }
}

泛型:是把类型做到了通用

泛型委托

using System;

namespace AdvancedDelegate
{
    delegate void GenericDelegate(T t);
    public class GenericDelegate
    {
        public static void InvokeDelegate()
        {
            GenericDelegate genericDelegate = new GenericDelegate(Method1);
            genericDelegate.Invoke("这个是泛型委托");
            GenericDelegate genericDelegate2 = new GenericDelegate(Method2);
            genericDelegate2.Invoke(99);


            Action action = new Action(Method1);
            action.Invoke("我是Action泛型委托的官方版本,不带有返回值");


            Func func = new Func(Method3);
            func.Invoke("我是带返回值的Func泛型委托,带有返回值的");
        }
        public static string InvokeDelegate1()
        {
            Func func = new Func(Method3);
            return func.Invoke("我是带返回值的Func泛型委托,带有返回值的");
        }
        public static void Method1(string str)
        {
            Console.WriteLine(str);
        }

        public static void Method2(int num)
        {
            Console.WriteLine("我是泛型委托2:" + num);
        }

        public static string Method3(string str)
        {
            return str;
        }
    }
}

反射:是找出DLL文件里面的各种信息 特性:让我们的类,方法,属性,参数之类的产生了更多的功能。在不修改源码的情况下(打一个标签就生成了新功能,本质它就是我们AOP的另一种实现方式) 委托:有一只小白兔,有一天出去玩跑东跑西的,后找不到妈妈了,然后通过委托叔叔找到了妈妈 学习一个技术,主要是记住技术的主要特点

委托与冒泡排序

namespace AdvancedDelegate
{
    public enum SortType
    {
        Ascending,
        Descending
    }
    /// 
    /// 
    /// 
    public static class SimpleSortSecond
    {
        public static void BubbleSort(int[] items, SortType sortType)
        {
            int i;
            int j;
            int temp;
            if (items == null)
            {
                return;
            }
            for (i = items.Length - 1; i >= 0; i--)
            {
                for (j = 1; j <= i; j++)
                {
                    bool swap = false;
                    switch (sortType)
                    {
                        case SortType.Ascending:
                            swap = items[j - 1] > items[j];
                            break;
                        case SortType.Descending:
                            swap = items[j - 1] < items[j];
                            break;
                        default:
                            break;
                    }
                    if (swap)
                    {
                        if (items[j - 1] > items[j])
                        {
                            temp = items[j - 1];
                            items[j - 1] = items[j];
                            items[j] = temp;
                        }
                    }

                }
            }
        }
    }
}

多播委托

【1】每一个委托都是继承自MulticastDelegate,每一个都是多播委托
【2】带返回值的多播委托,只返回最后一个方法的值
【3】多播委托,可以用+ -号,来操作方法的增加或者减少
【4】给委托传递相同方法时,生成的委托实例也是相同的(也是同一个委托)

using System;

namespace AdvancedDelegate
{
    delegate void MulticastTest();
    /// 
    /// 多播委托
    /// 
    public class MulticastDelegateTest
    {
        public void Show()
        {
            //自定义委托
            //MulticastTest multicastTest = new MulticastTest(MethodTest);
            //multicastTest.Invoke();

            Action action = new Action(MethodTest);
            action = (Action)MulticastDelegate.Combine(action, new Action(MethodTest2));
            action = (Action)MulticastDelegate.Combine(action, new Action(MethodTest3));
            action = (Action)MulticastDelegate.Remove(action, new Action(MethodTest3));
            action.Invoke();

            //简写
            Action action1 = MethodTest;
            action1 += MethodTest2;
            action1 += MethodTest3;
            action1 -= MethodTest3;
            action1.Invoke();
            //委托还可以循环获取
            foreach (Action item in action1.GetInvocationList())
            {
                item();
            }

            //带有返回值的委托
            Func func = () => { return "我是Lambda方法"; };
            func += () => { return "我是func1"; };
            func += () => { return "我是func2"; };
            func += () => { return "我是func3"; };
            func -= () => { return "我是func3"; };//匿名方法,创建一个新的方法,所以返回还是【我是func3】每个匿名方法都不一样
            func -= () => { return "我是func3"; };
            func += GetTest;
            func -= GetTest;//方法相同,会进行加+ -
            string resoult = func();
            Console.WriteLine(resoult);//带返回值的多播委托,只返回最后一个方法的值
        }
        public void MethodTest()
        {
            Console.WriteLine("我是方法MethodTest()");
        }
        public void MethodTest2()
        {
            Console.WriteLine("我是方法MethodTest2()");
        }
        public void MethodTest3()
        {
            Console.WriteLine("我是方法MethodTest3()");
        }
        public string GetTest()
        {
            return "我是方法GetTest()";
        }
    }
}

委托–事件:什么叫事件?事件就是委托的安全版本。第一点–在定义事件类的外部,他是不能使用=号来操作,只能用+=。第二点,在定义事件类的外部不能调用事件。另外事件就是委托的前面增减一个event关键字
using System;

namespace AdvancedEvent
{
    delegate void StudentDelegate();//【1】定义一个委托
    class Program
    {
        static void Main(string[] args)
        {
            EventFunction eventFunction = new EventFunction();
            InvokeDefine invokeDefine = new InvokeDefine();
            invokeDefine.StudentEvent += eventFunction.Student1;//【3】订阅事件
            invokeDefine.StudentEvent += eventFunction.Student2;//事件中添加方法
            invokeDefine.Invoke();
            Console.ReadKey();
        }
    }
    /// 
    /// 定义事件和调用事件,一定要放在一个类里面
    /// 
    class InvokeDefine//【2】定义一个调用和定义事件的类【定义和调用放在一个类里面,是为了安全】
    {
        public event StudentDelegate StudentEvent;//委托的事件,不能放在类的外部
        public void Invoke()
        {
            StudentEvent?.Invoke();//空引用运算符?.
            //相当于
            //if (StudentEvent != null)
            //{
            //    StudentEvent.Invoke();
            //}
        }
    }
    class EventFunction//【4】订阅者
    {
        //实例化委托
        public void Student1()
        {
            Console.WriteLine("我是一号学员");
        }
        public void Student2()
        {
            Console.WriteLine("我是二号学员");
        }
    }
}


WinForm里的事件

using System;
using System.Windows.Forms;

namespace EventDelegate
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("button1_Click");
        }
        private void button2_Click(object sender, EventArgs e)
        {
            MessageBox.Show("button2_Click");
        }
        private void button3_Click(object sender, EventArgs e)
        {
            MessageBox.Show("button3_Click");
        }
    }
}

            this.button1.Location = new System.Drawing.Point(434, 101);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            this.button1.Click += this.button2_Click;
            this.button1.Click += this.button3_Click;

自定义标准事件

using System;

namespace StudentEvent
{
    class Program
    {
        static void Main(string[] args)
        {
            Publisher publisher = new Publisher();
            Subscriber subscriber = new Subscriber("Subscriber", publisher);
            Subscriber2 subscriber2 = new Subscriber2("Subscriber2", publisher);
            //调用引发事件的方法
            publisher.DoSomething();
            Console.ReadKey();
        }
    }

    //事件发布者:事件的定义和调用   触发事件也可以写在这里
    class Publisher//订阅者
    {
        public event EventHandler CustomEvent;//事件

        public void DoSomething()
        {
            //调用之前可以在这里写一些其他的东西
            OnCustomEvent(new CustomEventArgs("我是事件参数"));

        }



        //虚方法可以进行重新
        //在受保护的虚方法中包装事件的调用,这样就允许派生类重新调用行为
        protected virtual void OnCustomEvent(CustomEventArgs e)
        {
            //CustomEvent?.Invoke(this, e);
            CustomEvent?.Invoke(this, e);
        }
    }




    //事件参数
    class CustomEventArgs : EventArgs
    {
        public CustomEventArgs(string message)
        {
            Message = message;
        }
        public string Message { get; set; }
    }
    //事件订阅:事件方法编写和订阅功能
    class Subscriber
    {
        //订阅的动作要在这里面了,所以要传传过来发布者
        public Subscriber(string str, Publisher publisher)
        {
            Str = str;
            //订阅事件
            publisher.CustomEvent += HanderCustomEvent;
        }

        private readonly string Str;
        private void HanderCustomEvent(object sender, CustomEventArgs e)
        {
            //在这里做想做的事情
            Console.WriteLine($"发布者:{sender.GetType()},订阅者:{Str},参数是:{e.Message}");
        }
    }

    //订阅者可以无限
    class Subscriber2
    {
        //订阅的动作要在这里面了,所以要传传过来发布者
        public Subscriber2(string str, Publisher publisher)
        {
            Str = str;
            //订阅事件
            publisher.CustomEvent += HanderCustomEvent;
        }

        private readonly string Str;
        private void HanderCustomEvent(object sender, CustomEventArgs e)
        {
            //在这里做想做的事情
            Console.WriteLine($"发布者:{sender.GetType()},订阅者:{Str},参数是:{e.Message}");
        }
    }
}

示例代码
https://github.com/KuKuDePerson/CSharpAdvancedDelegate

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/910781.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号