委托与事件

      委托与事件

引用面试题来说下委托与事件

C#中的委托是什么?事件是不是一种委托?事件和委托的关系。

委托可以把一个方法作为参数代入另一个方法。

委托可以理解为指向一个函数的指针。

委托和事件没有可比性,因为委托是类型,事件是对象,下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别。事件的内部是用委托实现的。因为对于事件来讲,外部只能“注册自己+=、注销自己-=”,外界不可以注销其他的注册者,外界不可以主动触发事件,因此如果用Delegate就没法进行上面的控制,因此诞生了事件这种语法。事件是用来阉割委托实例的,类比用一个自定义类阉割List。事件只能addremove自己,不能赋值。事件只能+=-=,不能= 。加分的补充回答:事件内部就是一个private的委托和addremove两个方法

文件操作:

第一步:声明一个文件流

FileStream fs=new FileStream(ofd.FileName,)

第二步:创建读取器

委托是一种数据类型

就像类一样,类也是一种数据类型

类使用之前需要定义一个类public class...

委托使用之前也需要定义一个委托public delegate....

类定义好后使用时需要声明类的变量,然后new一个类的对象

委托定义好后,使用时,也需要

什么时候用委托,为什么要用委托

当需要保存一个方法的时候使用委托,当要再程序中把方法本身作为参数传递时使用委托。

在程序运行中 有时候要传入一个方法,时这时要需要委托

定义一个委托注意:

1.委托的返回值类型,取决于将来要保存的方法是否有返回值类型

2.委托有没有参数,取决于将来要保存的方法是否有参数及参数的个数与类型

3.委托就像一个没有任何实现的方法一样,以"分号"结尾

4.定义委托需要关键字delegate

public delegate void MyDlegate();

委托对象本身其实并不能被调用 方法名();最终编译后,其实是调用了委托对象的Invoke()方法

调用该方法,就相当于调用了用户传过来的方法

在使用委托变量前,就像使用对象一样,最好判断一下对象是否为null,避免异常

下面来举例子说明一下

用排序的方法来说明这个问题。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace _04委托练习排序

{

    class Program

    {

        static void Main(string[] args)

        {

            Compare cp = new Compare();

            //object[] arr = { 1, 25, 24, 12, 23, 65, 42, 10, 88 };

            //object[] arr1 = { "素困", "样中考", "勒布朗怎么说", "科比布莱恩特说"};

            //声明一个委托

            //int[] arr =objs in

            object[] objs = {

                             new Person("张山",21),

                             new Person("里氏",29),

                             new Person("无误",11),

                             new Person("照亮",41),

                             new Person("前期",31),

                           };

            CompareToDelegate cd2 = new CompareToDelegate(CompareToPerson);

             //CompareToDelegate cd=new CompareToDelegate(CompareToInt);

             //CompareToDelegate cd1 = new CompareToDelegate(CompareToString);

            

            cp.CompareObject(objs, cd2);

            for (int i = 0; i < objs.Length; i++)

            {

                Console.WriteLine(((Person)objs).Name+"***"+((Person)objs).Age);

            }

            Console.ReadKey();

        }

        //定义一个比较int类型的方法

        static bool CompareToInt(object n1, object n2)

        {

            

            if ((int)n1 > (int)n2)

            {

                return true;

            }

            return false;

        }

        //定一个比较字符串类型的方法

        static bool CompareToString(object obj1, object obj2)

        {

            if (obj1.ToString().Length > obj2.ToString().Length)

            {

                return true;

            }

            return false;

        }

        //定于一个比较person的方法 根据年龄来比较

        static bool CompareToPerson(object obj1, object obj2)

        {

            Person p1 = obj1 as Person;

            Person p2 = obj2 as Person;

            if (p1.Age > p2.Age)

            {

                return true;

            }

            return false;

        }

    }

    public class Compare

    {

        public void CompareObject(object[] objs, CompareToDelegate cd)

        {

            for (int i = 0; i < objs.Length - 1; i++)

            {

                for (int j = 0; j < objs.Length - 1 - i; j++)

                {

                    if (cd(objs[j], objs[j + 1]))

                    {

                        object temp = objs[j];

                        objs[j] = objs[j + 1];

                        objs[j + 1] = temp;

                    }

                }

            }

        }

    }

    public delegate bool CompareToDelegate(object obj1,object obj2);

    class Person

    {

        public Person() { }

        string _name = null;

        public string Name

        {

            get { return _name; }

            set { _name = value; }

        }

        int _age;

        public int Age

        {

            get { return _age; }

            set { _age = value; }

        }

        public Person(string name, int age)

        {

            this._age = age;

            this._name = name;

        }

      

    }

}

事件是依靠委托来实现的

委托的不合理:

1.0委托可以直接通过“等号”来赋值,所以可以将前面的注册的处理程序全部覆盖掉,这样做不合适

2.0直接调用委托,触发由于3连接事件只要求只能在点击3次用户控件中的按钮才能被触发

所以在任何地方都恩那个触发该事件是不合理的。

定义一个事件,注意:使用事件来实现,与使用委托

1.0事件是不能在外界触发的,只能在类的内部使用(不能在外面像委托那么直接调用) 就避免了随意被触发的问题

当加了event关键字后,该事件只能在定义事件的类中来触发,绝不能在外部触发,虽然事件定义时使用了关键字public

当你写一个事件的时候,编译器会自动给你3个方法,一个是私有委托,一个公有添加事件的方法,一个公有删除事件的方法

委托和事件的区别:

委托和事件是没有可比性的,因为委托是数据类型,事件是对象(可以理解为对委托变量的封装)委托对象

下面说的是委托的对象(用委托的方式来实现的事件)和(标准的event方式实现)事件的区别,事件的内部是委托实现的。

因为对象事件来讲,外部只能“注册直接+=”,注销自己-=“,外界不可以注销其他的注册这,外界不可以主动触发事件,

因此如果用delegate就没法进行上面的控制,因此诞生了事件这种语法。add  remove

事件是用来阉割委托的实例的。事件只能addremove自己,不能赋值。事件只能+=-=不能=

实现事件的步骤

1.0定义委托类型

2.0定义事件变量 你在那个类中使用就定义在那个类中

3.0在条件符合时触发这个事件

4.0注册这个事件

委托的作用:

占位,在不知道将来要执行的方法的具体代码时,可以先用一个委托变量来代替方法调用(委托的返回值,参数列表要确定)

在实际调用之前,需要为委托赋值,否则为空。

事件的作用:

事件的作用和委托变量一样,只是在功能上变量有更多的限制。(比如:1.只能通过+=或者

-=来绑定方法(事件处理程序))2.只能在类内部调用(触发事件)

元数据:就是描述自己的信息

类型元数据:描述类型本身的信息

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值