C#基础-委托与事件
2013-12-04 21:26
871 查看
委托与事件是一堆相互关联的概念,委托是一种引用类型,可用于封闭命名方法或你们方法;事件可以使类或对象像其他类或对象通知发生的相关事情。因为灵活的事件处理要求将事件的相应分派给相应的事件处理方法,而C#中事件处理方法通常都是委托实现的。委托也可以用作回调,这样一个类可以告诉另一类:“执行这个操作,干完后通知我”。
委托可以多次出现在一个调用列表中。这种情况下,它每出现一次,就会被调用一次。在这样的调用列表中,当移除委托时,实际上移除的是调用列表中最后出现的那个委托实例。就在执行最后一条语句cd3 -= cd1;之前,委托cd3引用了一个空的调用列表。视图从空的列表中移除委托(或者从非空列表中移除表中没有的委托)不算是错误。
看一个经典的委托例子:
![](https://img-blog.csdn.net/20131204213419031?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYTFiMmMzMDA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
有两个进度条,用委托的方法来实现:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Ch09Ex01 { class Program { //declare a delegate named D,parameter int x delegate void D(int x); class C { public static void M1(int i) { Console.WriteLine("C.M1:" + i); } public static void M2(int i) { Console.WriteLine("C.M2:" + i); } public void M3(int i) { Console.WriteLine("C.M3:" + i); } } static void Main(string[] args) { D cd1 = new D(C.M1); cd1(-1); //C.M1:-1 D cd2 = new D(C.M2); cd2(-2); //C.M2:-2 D cd3 = cd1 + cd2; //cd1+cd2 cd3(10); //C.M1:10 C.M2:10 cd3 += cd1; //cd1+cd2+cd1 cd3(20); //C.M1:20 C.M2:20 C.M1:20 C c = new C(); D cd4 = new D(c.M3); cd3 += cd4; //cd1+cd2+cd1+cd4 cd3(30); //C.M1:30 C.M2:30 C.M1:30 C.M3:30 cd3 -= cd1; //cd1+cd2+cd4 cd3(40); //C.M1:40 C.M2:40 C.M3:40 cd3 -= cd4; //cd1+cd2 cd3(50); //C.M1:50 C.M2:50 cd3 -= cd2; //cd1 cd3(60); //C.M1:60 cd3 -= cd2;//cd1 cd3(60); //C.M1:60 cd3 -= cd1; //no delegate //cd3(70); //“System.NullReferenceException”类型的未经处理的异常出现在 Ch09Ex01.exe 中。其他信息: Object reference not set to an instance of an object. cd3 -= cd1; // Console.ReadKey(); } } }
委托可以多次出现在一个调用列表中。这种情况下,它每出现一次,就会被调用一次。在这样的调用列表中,当移除委托时,实际上移除的是调用列表中最后出现的那个委托实例。就在执行最后一条语句cd3 -= cd1;之前,委托cd3引用了一个空的调用列表。视图从空的列表中移除委托(或者从非空列表中移除表中没有的委托)不算是错误。
看一个经典的委托例子:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DalegateGreat { class Program { static void Main(string[] args) { Console.WriteLine("场景开始了...."); // 生成小王 小王 w = new 小王(); // 生成小账 小张 z = new 小张(); // 指定监视 z.PlayGame += new PlayGameHandler(w.扣钱); // 开始玩游戏 z.玩游戏(); Console.WriteLine("场景结束..."); Console.ReadLine(); } } // 负责扣钱的人 public class 小王 { public 小王() { Console.WriteLine("生成小王..."); } public void 扣钱(object sender, EventArgs e) { Console.WriteLine("小王:好小子,上班时间胆敢玩游戏..."); Console.WriteLine("小王:看看你小子有多少钱..."); 小张 f = (小张)sender; Console.WriteLine("小张的钱: " + f.钱.ToString()); Console.WriteLine("开始扣钱......"); System.Threading.Thread.Sleep(500); f.钱 = f.钱 - 500; Console.WriteLine("扣完了....现在小张还剩下:" + f.钱.ToString()); } } // 如果玩游戏,则引发事件 public class 小张 { // 先定义一个事件,这个事件表示“小张”在玩游戏。 public event PlayGameHandler PlayGame; // 保存小张钱的变量 private int m_Money; public 小张() { Console.WriteLine("生成小张...."); m_Money = 1000; // 构造函数,初始化小张的钱。 } public int 钱 // 此属性可以操作小张的钱。 { get { return m_Money; } set { m_Money = value; } } public void 玩游戏() { Console.WriteLine("小张开始玩游戏了....."); Console.WriteLine("小张:CS好玩,哈哈哈! 我玩....."); System.Threading.Thread.Sleep(500); System.EventArgs e = new EventArgs(); OnPlayGame(e); } protected virtual void OnPlayGame(EventArgs e) { if (PlayGame != null) { PlayGame(this, e); } } } // 定义委托处理程序 public delegate void PlayGameHandler(object sender, System.EventArgs e); }
有两个进度条,用委托的方法来实现:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; namespace ProgressBar { public partial class Form1 : Form { public Form1() { InitializeComponent(); } delegate void setProgressBar(int setValue); setProgressBar setProgress; public void setProgressMethod1(int value) { progressBar1.Value = value; } public void setProgressMethod2(int value) { progressBar2.Value = value; } private void button1_Click(object sender, EventArgs e) { setProgress = new setProgressBar(setProgressMethod1); setProgressBarValue(setProgress); setProgress = new setProgressBar(setProgressMethod2); setProgressBarValue(setProgress); } private void setProgressBarValue(setProgressBar setValue) { for (int i = 0; i <= 100; i++) { Application.DoEvents(); Thread.Sleep(50); setValue(i); } } } }
相关文章推荐
- C#基础系列--C#中委托与事件(一)
- unity基础之C#基础——[转]大白话系列之C#委托与事件讲解(一)
- [C#基础]委托与事件
- C#基础知识回顾--委托事件
- C#基础精华07(委托事件,委托的使用,匿名方法)
- C#基础-委托与事件
- C#事件和委托的基础知识模型收藏
- C#基础精华07(委托事件,委托的使用,匿名方法)
- C#控制台基础 事件可以在本类中当做委托来调用,但是在其他类不可以直接调用
- C#基础学习系列之:委托和事件
- 黑马程序员:C#基础篇(三)委托与事件
- C# 在线培训之零基础入门 05:委托与事件
- C#事件和委托的基础知识模型
- C#基础系列--C#中委托与事件(一)
- C#基础笔记——委托(Delegate)和事件(Event)
- C# 基础知识系列]专题六:.net WinForm 控件的事件委托剖析
- C#事件和委托的基础知识模型
- C#事件和委托的基础知识模型
- C#基础系列--C#中委托与事件(一)
- C#基础入门之委托事件反射