去年学习C#的时候按照进度把C#的委托和事件“认真”的学习了一下,自己知道委托和事件的重要性,所以也努力的学习,可说实也没怎么学懂。碰巧这段时间在做一个解析GPS数据的小项目,因为其中有需要条件自动判断并处理的模块,因此首先想到的就是委托和事件。借此机会重新学习和复习了一下,收获颇丰。

  什么是委托?根据我的理解委托就是把一件可能发生的事情,当满条件达到时委托别人帮忙处理。根据从书上看到的委托应该是有C++的函数指针发展而来的,只不过C#中一般不用指针。在这里举一个小例子,输入一个字符串当它的长度满足指定长度时输出,达到指定长度就是触发了事件。

class AutoDisposeStr
    {

public AutoDisposeStr(int length)
        {
            LimitLength = length;
        }
        public delegate void DisplaysrtHandler();
        public  DisplaysrtHandler MeetLength;

public void OnReadAndDisplay()
        {
            Console.WriteLine(str);
        }

public DisplaysrtHandler MeetLength
        {
           get { return _MeetLength; }
           set { _MeetLength = value; }
        }
        public int LimitLength
        {
            get { return _LimitLength; }
            set { _LimitLength = value; }
        }

public string str
        {
            get { return _str; }
            set
            {
                if (value.Length >= LimitLength)
                {
                    _str = value;
                    MeetLength();
                }
            }
        }

private int _LimitLength;
        private string _str;
        private DisplaysrtHandler _MeetLength;
    }
}

  首先构建了一AutoDisposeStr类有三个字段_LimitLength表示处理字符串的门限值对应的属性为LimitLength,_Str将要处理的字符串对应属性为Str,_MeetLength为委托类型的字段对应属性为MeetLength用来注册监听者。需要注意的是委托类型参数列表和你处理函数的参数列表需要对应,在这里就是 public delegate void DisplaysrtHandler()和public void OnReadAndDisplay()。因为要实时监听字符串长度是否达到门限值,所以要在字符串属性赋值时进行处理。每输入一个字符串,判断长度是否达到门限值,如果达到则调用监听函数处理:

public string str
        {
            get { return _str; }
            set
            {
                if (value.Length >= LimitLength)
                {
                    _str = value;
                    MeetLength();//调用监听函数处理
                }
            }

在这里其实就是把处理的方法委托给了public void OnReadAndDisplay()函数。最后只需要在Main()函数中实例化并注册监听函数即可。委托的用法就这么简单,不过有几点组要注意:

  一:如果当前没有订阅者也就是MeetLength为空执行 MeetLength()会引发异常NullReferenceException,因此为了解决这个问题在触发事件之前检查空值。

DisplaysrtHandler local=MeetLength;

if(local!=null)

{

  local();

}

这里定义了一个局部变量来检查是否为空是为了防止来自不同线程订阅者被移除可能造成NullReferenceException异常,因为MeetLength-=<listener>,会将一个全新的委托指派给MeetLength,这不会对原先local委托有任何影响。

    二,委托链会按注册的顺序调用,但是如果一旦前面的委托发生异常,后面的委托将得不到执行。因此最保险的方法应该用foreach(DisplaysrtHandler myhander in local.GetInvocationList){}同时加上异常处理。

委托就说这么多吧,说的不对的地方欢迎指正共同学习。

接下来说说事件,我感觉事件就是在委托的基础上增加了一些编程的规范。对于委托你可以在任何包容类之外调用委托,这就会造成对包容类内委托结果的影响。不满足封装性要求,其次事件中当注册事件和移除事件时如果不幸将“-=”或“+=”写成了“=”在委托中没有语法错误而是造成了委托连被无意赋值号覆盖掉了,而在事件中这样的大意是不能编译通过的。防止了这种错误的可能性,还有事件中对事件处理函数参数有规范要求,这里就不多讲了。贴上事件的代码以做对比:

class AutoDisposeStr
    {

public class AutoDisposeStrArgs : System.EventArgs
        { }
        public AutoDisposeStr(int length)
        {
            LimitLength = length;
        }
        public delegate void DisplaysrtHandler(object sender, AutoDisposeStrArgs newAutoDisposeStr);
        public event DisplaysrtHandler MeetLength;

public void OnReadAndDisplay(object sender, AutoDisposeStrArgs newAutoDisposeStr)
        {
            Console.WriteLine(str);
        }

//public DisplaysrtHandler MeetLength
        //{
        //    get { return _MeetLength; }
        //    set { _MeetLength = value; }
        //}
        public int LimitLength
        {
            get { return _LimitLength; }
            set { _LimitLength = value; }
        }

public string str
        {
            get { return _str; }
            set
            {
                if (value.Length >= LimitLength)
                {
                    _str = value;
                    MeetLength(this,null);
                }
            }
        }

private int _LimitLength;
        private string _str;
        //private DisplaysrtHandler _MeetLength;
    }

主函数:

class Program
    {
        static void Main(string[] args)
        {
            AutoDisposeStr ads= new AutoDisposeStr(5);
            ads.MeetLength += ads.OnReadAndDisplay;
            for (int i = 0; i < 10; i++)
            {
                ads.str = Console.ReadLine();
            }
        }

本人也是初学者,有说的不对不妥的地方欢迎指正,共同学习,共同进步。

重读C#委托、事件有感的更多相关文章

  1. C# ~ 从 委托事件 到 观察者模式 - Observer

    委托和事件的部分基础知识可参见 C#/.NET 基础学习 之 [委托-事件] 部分: 参考 [1]. 初识事件 到 自定义事件: [2]. 从类型不安全的委托 到 类型安全的事件: [3]. 函数指针 ...

  2. C#委托,事件理解入门 (译稿)

    原文地址:http://www.codeproject.com/Articles/4773/Events-and-Delegates-Simplified 引用翻译地址:http://www.cnbl ...

  3. 关于ios使用jquery的on,委托事件失效

    $('.parents').on("click",'.child',function(){}); 类似上面这种,在ios上点击"child"元素不会起作用,解决 ...

  4. Observer设计模式中-委托事件-应用在消息在窗体上显示

    Observer设计模式:监视者模式.在类中的方法中处理的结果或者消息通过事件委托 的方式发送给主窗体. 因为在其它类中直接访问主窗体类,显示内容是不能直接调用控件赋值的,当然也有别的类似查阅控件名, ...

  5. Asp.net用户控件和委托事件

    在Asp.net系统制作过程中,门户类型的网站,我们可以用DIV+CSS+JS+Ajax全部搞定,但是一旦遇到界面元素比较复杂的时候,还是UserControl比较方便一些,各种封装,各种处理,然后拖 ...

  6. jQuery里面的普通绑定事件和on委托事件

    以click事件为例: 普通绑定事件:$('.btn1').click(function(){}绑定 on绑定事件:$(document).on('click','.btn2',function(){ ...

  7. c#基础学习笔记-----------委托事件

    这里有一个比较简单的委托实例应用(跨窗体操作控件) http://blog.csdn.net/bdstjk/article/details/7004035 还有一个比较详细的介绍并深入理解委托事件的讲 ...

  8. c#委托事件入门--第二讲:事件入门

    上文 c#委托事件入门--第一讲:委托入门 中和大家介绍了委托,学习委托必不可少的就要说下事件.以下思明仍然从事件是什么.为什么用事件.怎么实现事件和总结介绍一下事件 1.事件是什么:. 1.1 NE ...

  9. Unity C#笔记 委托&事件

    C#的委托与事件搭配,即是观察者模式的一种实现. 因为观察者模式的原理很易懂,不作多讲,本文纯粹用于记录语法. delegate(委托) //声明没有参数,没有返回值的委托类型XXXX public ...

  10. JavaScript中事件委托(事件代理)详解

    在JavaScript的事件中,存在事件委托(事件代理),那么什么是事件委托呢? 事件委托在生活中的例子: 有三个同事预计会在周一收到快递.为签收快递,有两种办法:一是三个人在公司门口等快递:二是委托 ...

随机推荐

  1. ( 译、持续更新 ) JavaScript 上分小技巧(三)

    最近家里杂事较多,自学时间实在少的可怜,所以都在空闲时间看看老外写的内容,学习之外顺便翻译分享~等学习的时间充足些再写写自己的一些学习内容和知识点分析(最近有在接触的:复习(C#,SQL).(学习)T ...

  2. 一个WPF控件 诡异的MouseEvent 。

    背景: private System.Windows.Controls.Border _borderTouch; private bool _mouseDown = false;  private S ...

  3. 使用WebService和不使用WebService哪个速度更快哪个更安全

  4. SQL Server 2012 学习笔记3 增查改删

    现在举例几个"增查改删"的语句 select * from UserInfor --查找所有字段 select username,UserId from UserInfor -- ...

  5. phpcms后台获取当前登录账号的数据

    $amdinid=$_SESSION['userid'];$infoadmin=$this->admin->get_one(array('userid'=>$amdinid)); v ...

  6. oracle表字段为汉字,依据拼音排序

    在order by后面使用NLSSORT函数转化汉字列,如下 select * from student order by NLSSORT(name,'NLS_SORT=SCHINESE_PINYIN ...

  7. JavaWeb学习笔记——开发动态WEB资源(七)bookapp

    该工程的功能是实现一个bookapp 1.开发注册页面,注册使用properties文件,存储在classpath跟路径 2.注册成功跳转到登录页面 3.输入用户名密码登录,登录成功跳转到book显示 ...

  8. 入门:HTML:hello world!

    <html> <head> </head> <body> <h1>hello world!</h1> </body> ...

  9. 深刻认识一下session

    session是什么: session即会话,是一种持续性,双向的连接. session和cookie在本质上没什么区别,都是针对http协议的局限性提出的一种保持客户端和服务端会话状态的机制. se ...

  10. [Unity] 2D开发学习教程

    豆子先生,据说是官方的一个Demo, 在蛮牛网上有大部分代码的视频讲解. 这个是我学习过程中边看教程边写出来的,功能和原版基本一样,增加了手游的操控. Blog: http://www.cnblogs ...