委托与事件

委托在底层就是一个函数的指针,委托是事件的基础。

你可以传递引用类型、值类型、但是你有没有需要传一个方法呢?传方法的过程就是委托。

消息类:

 public class Message
    {
        /// <summary>
        /// 传引用类型
        /// </summary>
        /// <param name="msg"></param>
        public static void Send(string msg)
        {
            Console.WriteLine("你传递的参数是string:{0}", msg);
        }

        /// <summary>
        /// 传值类型
        /// </summary>
        /// <param name="msg"></param>
        public static void Send(int msg)
        {
            Console.WriteLine("你传递的参数是int:{0}", msg);
        }

        /// <summary>
        /// 利用委托传一个方法过来
        /// </summary>
        /// <param name="msg"></param>
        public static void Send(Action msg)
        {
            ///执行它
            msg.Invoke();
         //   Console.WriteLine("你传递的参数是int:{0}", msg);
        }
    }

使用例子:

 class Program
    {
        static void Main(string[] args)
        {
            ///传引用类型的字符串
            Message.Send("晚上好!端午节快乐!");

            ///传值类型的,int 68
            Message.Send(68);

            ///传一个方法
            Message.Send(SendMessage);

            Console.ReadKey();

        }

        /// <summary>
        /// 方法
        /// </summary>
        static void SendMessage()
        {
            Console.WriteLine("我是 Program 类的 SendMessage 方法");
        }
    }

运行结果:

是不是很有用处:

当两个对象之间的处理结果需要相互通知。(onClick,onLoad等一切的事件,基础都是基于委托),委托实际就是一个观察者模式。其作用是两个对象之间可以通过委托,相互通知消息。

委托的定义:

    public class DelegateExample
    {

        /// <summary>
        /// 定义一个方法,方法有0到N个参数,可以有返回值,和无返回值
        /// </summary>
        /// <param name="msg"></param>
        public void MethodTest(int Ivalue) { }

        /// <summary>
        /// 定义另一个委托,委托和方法一样有0到N个参数,可以有返回值,和无返回值
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="msg2"></param>
        public delegate int DelegateTest(string msg, string msg2);

        public void Show()
        {
            ///定义委托:委托像 “类” 一样,定义来使用,用 new DelegateTest 来指向方法
            DelegateTest delegateTest1 = new DelegateTest(DelegateTest2_Mothod);

            ///调用委托:将参数给定
            delegateTest1.Invoke("aa", "bb");
            Console.WriteLine("------------------------------------");
            ///直接指向方法
            DelegateTest delegateTest2 = DelegateTest2_Mothod;
            ///不用 Invoke 也可以直接使用
            delegateTest1("cc", "dd");

            Console.WriteLine("------------------------------------");

            ///用 Lambda 表达式来定义一个匿名方法
            DelegateTest delegateTest3 = (string msg, string msg2) => { Console.WriteLine("BeginInvoke"); return msg.Length + msg2.Length; };

            ///异步来调用
            delegateTest3.BeginInvoke("ee", "ff", null, null);
            Console.WriteLine("------------------------------------");
            ///用 Lambda 表达式来定义一个匿名方法
            DelegateTest delegateTest4 = (string msg, string msg2) => { Console.WriteLine("执行委托"); return msg.Length + msg2.Length; };

            ///多次指定方法(多播委托)
            delegateTest4 += (string msg, string msg2) => { Console.WriteLine("执行委托"); return msg.Length + msg2.Length; };

            delegateTest4 += DelegateTest2_Mothod;

            delegateTest4 += DelegateTest2_Mothod;
            ///减掉一个
            delegateTest4 -= DelegateTest2_Mothod;

            ///减掉一个匿名委托,实际是不起作用的,因为匿名没有“固定”指向名称,所以不能减掉,下面同样会执行
            delegateTest4 -= (string msg, string msg2) => { Console.WriteLine("执行委托"); return msg.Length + msg2.Length; };

            delegateTest4.Invoke("dd", "eee");
        }

        int DelegateTest2_Mothod(string msg, string msg2)
        {
            Console.WriteLine("执行委托");
            return msg.Length + msg2.Length;
        }

    }

执行结果是:

delegateTest1  直接用(delegateTest1("cc", "dd");),Invoke调用,delegateTest1.Invoke("aa", "bb");两次结果完全相同

delegateTest3 begininvoke 是在前面的,结果跑到最后面。异步的原因。

delegateTest4 加了4次委托,减掉2次,但是执行3次,说明了有一次没有减掉。就是匿名没有减掉。

记住委托的作用就是,定义一个方法(函数)的指针。

在编程中,委托是一个非常有用的功能,因为任何异步调用的基础也是委托

.net 框架为我们定义好了两个委托,一个有返回值,一个无返回值,这样我们就免于需要创建委托的重复劳动:

无返回

Action
Action<string>
0-16个参数,无返回值

在系统当中大量使用

有返回

func<int>
fun<string,int> 第一个是参数,最后是返回值
1-17,前面是参数,最后一个是返回值

在系统当中大量使用

1、异步必须要用委托
2、方法像类型一样传递,可以分离业务逻辑

事件的基础就是委托:

事件在系统中使用的非常之多。

定义一个事件:

        /// <summary>
        ///  定义一个事件
        /// </summary>
        public event Action<string> SendEvent;

事件的使用:

        static void Main(string[] args)
        {
            ///传引用类型的字符串
            Message.Send("晚上好!端午节快乐!");

            ///传值类型的,int 68
            Message.Send(68);

            ///传一个方法
            Message.Send(SendMessage);

            DelegateExample delegateExample = new DelegateExample();
            delegateExample.Show();

            ///实例化事件类
            MyEvent myevent = new MyEvent();

            ///订阅事件
            myevent.SendEvent += Myevent_SendEvent;

            ///执行工作
            myevent.Send(string.Format("开始:{0}", DateTime.Now));

            Console.ReadKey();

        }

        /// <summary>
        /// 订阅的处理方法(确定委托需要指针,指向的方法)
        /// </summary>
        /// <param name="obj"></param>
        private static void Myevent_SendEvent(string obj)
        {
            Console.WriteLine("返回:{0}", obj);
        }

事件演示代码:

  public class MyEvent
    {

        /// <summary>
        /// 方法的定义
        /// </summary>
        /// <param name="msg"></param>
        public void MethodDemo(string msg)
        { }

        /// <summary>
        /// 委托的定义,委托在方法修饰符后面加 delegate
        /// 委托没有实体{}
        /// </summary>
        /// <param name="msg"></param>
        public delegate void delegateDemo(string msg);

        /// <summary>
        /// 事件的定义,事件在委托修饰符后面加 event
        /// </summary>
        public event delegateDemo eventDemo;

        /// <summary>
        ///
        /// 记住,事件必须以一个委托为基础
        ///  定义一个事件,本例中以系统自带的 Action 为基础
        ///
        /// </summary>
        public event Action<string> SendEvent;

        public void Send(string msg)
        {

            Task.Factory.StartNew(() =>
            {

                Thread.Sleep(TimeSpan.FromSeconds(15));

                ///在
                if (SendEvent != null)
                {
                    SendEvent(string.Format("Task.Factory.StartNew:{0},{1}", DateTime.Now, msg));
                }
            });

        }

    }

运行结果:

委托是一种类型、是一个函数指针、事件就是委托的一个实例

委托加上一个 EVENT 关键字后就变成了事件

事件不能直接赋值。也不能被调用。只能通过+=,-= 来操作委托

委托就是 观察者模式 的实现方法

委托是业务之间逻辑剥离的解决方案。

时间: 2024-10-05 04:44:57

委托与事件的相关文章

C#高级知识点概要(1) - 委托和事件

作者:linybo 要成为大牛,必然要有扎实的基本功,不然时间再长项目再多也很难有大的提升.本系列讲的C# 高级知识点,是非常值得去撑握的,不仅可以让你写代码时游刃有余,而且去研究和学习一些开源项目时,也不会显得那么吃力了. 希望大家记住,这里讲的所有的知识点,不仅仅是了解了就可以了,还要会灵活用,一定要多思考,撑握其中的编程思想. 本文讲的是委托和事件,这两个词可能你早就耳熟能详,但你是否真正撑握了呢? 本系列讲的C#高级知识点都是要求开发时能达到可以徒手写出来的水平(不依赖搜索引擎.找笔记等

C#学习(一):委托和事件

预备知识 在学习委托和事件之前,我们需要知道的是,很多程序都有一个共同的需求,即当一个特定的程序事件发生时,程序的其他部分可以得到该事件已经发生的通知. 而发布者/订阅者模式可以满足这种需求.简单来说,在这种模式中,发布者定义了一系列程序的其他部分可能感兴趣的事件.其他类可以"注册",以便再这些事件发生时发布者可以通知它们.这些订阅者类通过向发布者提供一个方法来"注册"以获取通知.当事件发生时,发布者"触发事件",然后执行订阅者提交的所有事件.

C#中委托和事件

目 录 1.1 理解委托 2 1.1.1 将方法作为方法的参数 2 1.1.2 将方法绑定到委托 4 1.2 事件的由来 6 1.2.1 更好的封装性 6 1.2.2 限制类型能力 9 1.3 委托的编译代码 10 1.4 .NET 框架中的委托和事件 11 1.4.1 范例说明 11 1.4.2 Observer 设计模式简介 12 1.4.3 实现范例的Observer 设计模式 13 1.4.4 .NET 框架中的委托与事件 14 1.5 委托进阶 16 1.5.1 为什么委托定义的返回值

C#委托和事件定义和使用

委托 定义委托的语法和定义方法比较相似,只是比方法多了一个关键字delegate ,我们都知道方法就是将类型参数化,所谓的类型参数化就是说该方法接受一个参数,而该参数是某种类型的参数,比如int.string等等:而委托是将方 法参数化,说了上面的那个类型参数化之后,相信你也能猜到方法参数化的意思了,对,就是将方法作为一个参数传到一个委托中. 首先来看看声明委托的语句: public deletate void MyDelegate(); public:访问修饰符  delegate:关键字 

[转载]C#深入分析委托与事件

原文出处: 作者:风尘浪子 原文链接:http://www.cnblogs.com/leslies2/archive/2012/03/22/2389318.html 同类链接:http://www.cnblogs.com/SkySoot/archive/2012/04/05/2433639.html 引言 本篇文章将为你介绍一下 Delegate 的使用方式,逐渐揭开 C# 当中事件(Event)的由来,它能使处理委托类型的过程变得更加简单.还将为您解释委托的协变与逆变,以及如何使用 Deleg

[转载]C#委托和事件(Delegate、Event、EventHandler、EventArgs)

原文链接:http://blog.csdn.net/zwj7612356/article/details/8272520 14.1.委托 当要把方法作为实参传送给其他方法的形参时,形参需要使用委托.委托是一个类型,是一个函数指针类型,这个类型将该委托的实例化对象所能指向的函数的细节封装起来了,即规定了所能指向的函数的签名,也就是限制了所能指向的函数的参数和返回值.当实例化委托的时候,委托对象会指向某一个匹配的函数,实质就是将函数的地址赋值给了该委托的对象,然后就可以通过该委托对象来调用所指向的函

C#语法之委托和事件

从大学就开始做C#这块,也做C#几年了,最近又从ios转回.Net,继续做C#,之前也没有写博客的习惯,写博客也是从我做ios的时候开始的,现在既然又做回了.net,那就写点关于.Net的博客,可能在大牛眼里这些都是简单基础的,不过回过头看我当时初学的时候觉得委托事件是不容易理解的,我这里也是想着联系着OC,两者有比较的学习下.毕竟都是面向对象语言,思想是相通的. 委托在OC中类似block,都是指向一个函数,其实他没和C++的函数指针类似.但委托还是和函数指针不太一样,委托是完全面向对象的,是

C#综合揭秘——深入分析委托与事件

本篇文章将为你介绍一下 Delegate 的使用方式,逐渐揭开 C# 当中事件(Event)的由来,它能使处理委托类型的过程变得更加简单.还将为您解释委托的协变与逆变,以及如何使用 Delegate 使 Observer(观察者)模式的使用变得更加简单.在事件的介绍上,会讲述事件的使用方式,并以ASP.NET的用户控件为例子,介绍一下自定义事件的使用.最后一节,将介绍Predicate<T>.Action<T>.Func<T,TResult>多种泛型委托的使用和Lamb

C#——委托与事件

首先,来了解一下什么是委托,什么是事件,这两者之间有什么区别? 委托: (1)是一种数据类型,可以像类一样声明数据类型,声明变量 (2)只有委托才能将方法当做变量来保存 (3)不同类型的方法需要使用不同的委托类型来存储,所以不同类型的方法需要定义不同的类来存储不同的对象 (4)同一种方法可以使用同一个委托类型来存储 先通过一小段代码来了解一下 //先定义一个委托,委托也可以声明变量,还有返回值 public delegate void MyDelegate(); public delegate