一、委托和事件

  委托和事件这两个概念是完全配合的。委托仅仅是函数指针,那就是说,它能够引用函数,通过传递地址的机制完成。委托是一个类,当你对它实例化时,要提供一个引用函数,将其作为它构造函数的参数。事件则是委托的一种表现形式。

委托的声明:[修饰符] delegate 返回类型 委托名(参数列表);

    简单的委托

View Code

using System;
using System;
using System.Collections.Generic;
using System.Text;namespace TestApp
{/// <summary>/// 委托/// </summary>/// <param name="s1"></param>/// <param name="s2"></param>/// <returns></returns>public delegate string ProcessDelegate(string s1, string s2);class Program{static void Main(string[] args){/*  调用方法  */ProcessDelegate pd = new ProcessDelegate(new Test().Process);Console.WriteLine(pd("Text1", "Text2"));}}public class Test{/// <summary>/// 方法/// </summary>/// <param name="s1"></param>/// <param name="s2"></param>/// <returns></returns>public string Process(string s1, string s2){return s1 + s2;}}
}

    泛型委托

View Code

using System;
using System.Collections.Generic;
using System.Text;namespace TestApp
{/// <summary>/// 委托/// </summary>/// <param name="s1"></param>/// <param name="s2"></param>/// <returns></returns>public delegate string ProcessDelegate<T,S>(T s1, S s2);class Program{static void Main(string[] args){/*  调用方法  */ProcessDelegate<string,int> pd = new ProcessDelegate<string,int>(new Test().Process);Console.WriteLine(pd("Text1", 100));}}public class Test{/// <summary>/// 方法/// </summary>/// <param name="s1"></param>/// <param name="s2"></param>/// <returns></returns>public string Process(string s1,int s2){return s1 + s2;}}
}

    委托的回调方法

View Code

using System;
using System.Collections.Generic;
using System.Text;namespace TestApp
{/// <summary>/// 委托/// </summary>/// <param name="s1"></param>/// <param name="s2"></param>/// <returns></returns>public delegate string ProcessDelegate(string s1, string s2);class Program{static void Main(string[] args){/*  调用方法  */Test t = new Test();string r1 = t.Process("Text1", "Text2", new ProcessDelegate(t.Process1));string r2 = t.Process("Text1", "Text2", new ProcessDelegate(t.Process2));string r3 = t.Process("Text1", "Text2", new ProcessDelegate(t.Process3));Console.WriteLine(r1);Console.WriteLine(r2);Console.WriteLine(r3);}}public class Test{public string Process(string s1,string s2,ProcessDelegate process){return process(s1, s2);}public string Process1(string s1, string s2){return s1 + s2;}public string Process2(string s1, string s2){return s1 + Environment.NewLine + s2;}public string Process3(string s1, string s2){return s2 + s1;}}
}

 事件的声明:[修饰符] event 委托名 事件名;

    事件应该由事件发布者触发,而不应该由客户端(客户程序)来触发。注意这里术语的变化,当我们单独谈论事件,我们说发布者(publisher)、订阅者(subscriber)、客户端(client)。当我们讨论Observer模式,我们说主题(subject)和观察者(observer)。客户端通常是包含Main()方法的Program类。

    1.为什么要使用事件而不是委托变量? (摘自http://kb.cnblogs.com/page/45756/)

View Code

using System;
using System.Collections.Generic;
using System.Text;// 实例:为什么使用事件而不是委托变量
namespace ConsoleApp
{class Program{static void Main(string[] args){Publishser pub = new Publishser();Subscriber sub = new Subscriber();pub.NumberChanged += new NumberChangedEventHandler(sub.OnNumberChanged);pub.DoSomething();            // 应该这样触发事件pub.NumberChanged("使用委托");        // 但是被这样调用了,对委托变量的恰当使用
        }}// 定义委托public delegate void NumberChangedEventHandler(string Name);// 定义事件发布者public class Publishser{private string Name;public NumberChangedEventHandler NumberChanged;                // 声明委托变量//public event NumberChangedEventHandler NumberChanged;    // 声明一个事件public void DoSomething(){// 在这里完成一些工作 ...if (NumberChanged != null){    // 触发事件
                NumberChanged(Name);}}}// 定义事件订阅者public class Subscriber{public void OnNumberChanged(string Name){Console.WriteLine("{0}已响应", Name);}}}

     2.如何让事件只允许一个客户订阅?(事件访问器)

View Code

using System;
using System.Collections.Generic;
using System.Text;// 实例:让事件只允许一个客户订阅
namespace ConsoleApp
{class Program3{static void Main(string[] args){Publishser pub = new Publishser();Subscriber1 sub1 = new Subscriber1();Subscriber2 sub2 = new Subscriber2();pub.NumberChanged -= sub1.OnNumberChanged;    // 不会有任何反应pub.NumberChanged += sub2.OnNumberChanged;    // 注册了sub2pub.NumberChanged += sub1.OnNumberChanged;    // sub1将sub2的覆盖掉了
pub.DoSomething();            // 触发事件
        }}// 定义委托public delegate string GeneralEventHandler();// 定义事件发布者public class Publishser{// 声明一个委托变量或事件都无所谓private GeneralEventHandler numberChanged;// 事件访问器的定义public event GeneralEventHandler NumberChanged{add{numberChanged = value; //只允许注册一个事件,重复注册则替换前者
            }remove{numberChanged -= value;}}public void DoSomething(){// 做某些其他的事情if (numberChanged != null){    // 触发事件string rtn = numberChanged();Console.WriteLine("Return: {0}", rtn);        // 打印返回的字符串
            }}}// 定义事件订阅者public class Subscriber1{public string OnNumberChanged(){Console.WriteLine("Subscriber1 Invoked!");return "Subscriber1";}}public class Subscriber2{public string OnNumberChanged(){Console.WriteLine("Subscriber2 Invoked!");return "Subscriber2";}}}

     3.处理异常和订阅者方法超时的处理

View Code

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.Remoting.Messaging;
using System.IO;// 处理异常
namespace ConsoleApp {class Program6 {static void Main(string[] args) {Publisher pub = new Publisher();Subscriber1 sub1 = new Subscriber1();Subscriber2 sub2 = new Subscriber2();Subscriber3 sub3 = new Subscriber3();pub.MyEvent += new EventHandler(sub1.OnEvent);pub.MyEvent += new EventHandler(sub2.OnEvent);pub.MyEvent += new EventHandler(sub3.OnEvent);pub.DoSomething();        // 触发事件
Console.WriteLine("Control back to client!\n");    // 返回控制权Console.WriteLine("Press any thing to exit...\n");Console.ReadKey();        // 暂停客户程序,提供时间供订阅者完成方法
        }}public class Publisher {public event EventHandler MyEvent;public void DoSomething() {            // 做某些其他的事情Console.WriteLine("DoSomething invoked!");if (MyEvent != null) {Delegate[] delArray = MyEvent.GetInvocationList();foreach (Delegate del in delArray) {EventHandler method = (EventHandler)del;method.BeginInvoke(null, EventArgs.Empty, null, null);}}}}public class Subscriber1 {public void OnEvent(object sender, EventArgs e) {Thread.Sleep(TimeSpan.FromSeconds(3));        // 模拟耗时三秒才能完成方法Console.WriteLine("Waited for 3 seconds, subscriber1 invoked!");}}public class Subscriber2 {public void OnEvent(object sender, EventArgs e) {throw new Exception("Subsciber2 Failed");    // 即使抛出异常也不会影响到客户端//Console.WriteLine("Subscriber2 immediately Invoked!");
        }}public class Subscriber3 {public void OnEvent(object sender, EventArgs e) {Thread.Sleep(TimeSpan.FromSeconds(2));    // 模拟耗时两秒才能完成方法Console.WriteLine("Waited for 2 seconds, subscriber3 invoked!");}}
}

     4.委托和方法的异步调用

View Code

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.Remoting.Messaging;namespace ConsoleApp
{public delegate int AddDelegate(int x, int y);class Program9{static void Main(string[] args){Console.WriteLine("--------客户端执行开始,即将调用异步");Thread.CurrentThread.Name = "客户端线程Name";Calculator cal = new Calculator();AddDelegate del = new AddDelegate(cal.Add);string data = "客户端数据."; //异步完成后挂载的方法返回的数据AsyncCallback callBack = new AsyncCallback(OnAddComplete); //异步完成后挂载方法del.BeginInvoke(2, 5, callBack, data);        // 异步调用方法// 做某些其它的事情,模拟需要执行3秒钟for (int i = 1; i <= 3; i++){Thread.Sleep(TimeSpan.FromSeconds(i));Console.WriteLine("{0}: 模拟执行其他事情 {1} 秒钟.",Thread.CurrentThread.Name, i);}Console.WriteLine("\n-------客户端执行完毕...");Console.ReadKey();}static void OnAddComplete(IAsyncResult asyncResult){AsyncResult result = (AsyncResult)asyncResult;AddDelegate del = (AddDelegate)result.AsyncDelegate;string data = (string)asyncResult.AsyncState;int rtn = del.EndInvoke(asyncResult);Console.WriteLine("{0}: 异步返回值, {1}; Data: {2}\n",Thread.CurrentThread.Name, rtn, data);}}public class Calculator{public int Add(int x, int y){if (Thread.CurrentThread.IsThreadPoolThread){Thread.CurrentThread.Name = "异步线程Name";}Console.WriteLine("--------异步开始!");// 执行某些事情,模拟需要执行2秒钟for (int i = 1; i <= 2; i++){Thread.Sleep(TimeSpan.FromSeconds(i));Console.WriteLine("{0}: 模拟执行事情 {1} 秒钟.",Thread.CurrentThread.Name, i);}Console.WriteLine("--------异步结束!");return x + y;}}
}

二、异常和错误 (try-catch-finally)

  基类:System.Exception

  try语句提供了一种机制来捕捉块执行过程中发生的异常。以下是它的三种可能的形式(s可多个catch):

●try-catch(s)
       ●try-finally
       ●try-catch(s)-finally

 try{申请资源,如数据库连接,网络连接,打开文件等可能出现异常的代码}

catch(异常类型 e){处理异常一类型的异常}

finally{释放资源}

手动跑出异常:throw new System.Exception();

转载于:https://www.cnblogs.com/wenmaoyu/p/3159808.html

3.0 面向对象 委托和事件 异常和错误相关推荐

  1. python 内存溢出能捕获吗_从0基础学习Python (19)[面向对象开发过程中的异常(捕获异常~相关)]...

    从0基础学习Python (Day19) 面向对象开发过程中的=>异常 什么是异常 ​ 当程序在运行过程中出现的一些错误,或者语法逻辑出现问题,解释器此时无法继续正常执行了,反而出现了一些错误的 ...

  2. C# 概念 委托和事件

    源码下载:http://www.tracefact.net/SourceCode/Delegates-and-Events-in-CSharp.rar C# 中的委托和事件 引言 委托 和 事件在 . ...

  3. [C#]委托和事件(讲解的非常不错)

    引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去 ...

  4. C# 关于委托和事件的妙文:通过一个例子详细介绍委托和事件的作用;Observer模式简介...

    委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见 ...

  5. 在C#中使用代理的方式触发事件 (委托和事件 ) (转)

    From:  http://www.cnblogs.com/gzhnan/articles/1859477.html 在C#中使用代理的方式触发事件 (委托和事件 ) 事件(event)是一个非常重要 ...

  6. C# 深入浅出 委托与事件

    C#中的委托和事件的概念接触很久了,但是一直以来总没有特别透彻的感觉,现在我在这里总结一下: 首先我们要知道委托的由来,为什么要使用委托了? 我们先看一个例子: 假设我们有这样一个需求,需要计算在不同 ...

  7. C#委托、事件、消息(入门级)

    本文的内容需要一定的OOP知识,不过我会在另一个内容介绍,由于实现细节,我会先写这部分. 大家关于委托.事件和消息大多是从WinForm编程接触的,首先是你在可视化的设计器里双击控件写所谓事件的处理代 ...

  8. C# 委托(Delegate) 事件(Event)应用详解

    委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每 ...

  9. [C#]委托和事件(详细讲解)

    引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去 ...

最新文章

  1. 反弹端口 HTTP代理 HTTP隧道技术
  2. 细胞膜内流体应力分析
  3. 《呐喊》金句摘抄(一)
  4. CTF-MISC杂项题2
  5. 利用文字技术帮助选购商品,慧眼“识”物的人都这样做……
  6. win2008r2 mysql 远程_SQL SERVER 2008 R2如何开启数据库的远程连接(转)
  7. python 注销一大段_Django框架用户注销功能实现方法分析
  8. 成为前端开发人员的步骤
  9. Linux Kernel 5.8 发布,华为内核代码贡献全球持续领先
  10. 2018ACM上海大都会赛: A. Fruit Ninja(这绝对是道原题+随机)
  11. leetcode371
  12. himawari-8卫星叶绿素a产品、_海洋卫星眼中的台风quot;海神quot;
  13. Java实现学生管理系统代码
  14. Android开发常用的模拟器
  15. 信息终端安全是指办公和生产用计算机,从办公终端安全角度考虑,以下哪个是正确的()...
  16. 从头学计量-中介效应理论介绍
  17. xxl子任务_分布式任务调度平台XXL-JOB
  18. Vue+elementUI走马灯实现界面3分钟无点击操作出现全屏banner
  19. Jeecgboot-Vue3 v1.2.0 版本正式发布,企业级低代码平台
  20. 代码:吃货联盟订餐系统

热门文章

  1. 在线2-36任意进制转换工具
  2. Spring依赖注入的模式和类型
  3. Vue和React组件之间的传值方式
  4. Unity热更新学习(二) —— ToLua c#与lua的相互调用
  5. 想搞一套AI问答游戏系统?简单,Google又开源了
  6. 如果一个国家是一种颜色,中国的颜色美哭了!
  7. [oracle]数据库字段类型char(n)的问题
  8. devExpress 7.2.5
  9. 第12章类和动态内存分配
  10. 关于互联网大厂裁员,引发企业危机处理与个人危机处理的思考