C#中的事件触发

  "创建并使用事件的步骤可以概括为事件建立代表,创建一个类来给事件处理程序传递参数,声明事件对应的代码,创建事件发生时执行的代码(处理程序)以及使事件发生"(最后一步可以理解为将事件处理程序和对象连接起来).

   上面是书上讲的一段话,它说的倒轻松啊,我可理解了挺长时间的,这可以说是我学C#到现在学得最晕的一次.

    首先说说代表,代表可以对应于C/C++当中的函数指针.看一个例子

namespace deleg1
{
 public class SortClass
 {
  static public int val1;
  static public int val2;

  public delegate void Sort(ref int a,ref int b);//代表的声明,可以认为是一个类

  public void DoSort(Sort ar)//创建一个函数,调用这个代表
  {
   ar(ref val1,ref val2);
  }
 }
 /// <summary>
 /// Class1 的摘要说明。
 /// </summary>
 class Class1
 {
  public static void Ascending(ref int first,ref int second)
  {
   if(first > second)
   {
    int tmp = first;
    first = second;
    second = tmp;
   }
  }

  public static void Descending(ref int first,ref int second)
  {
   if(first < second)
   {
    int tmp = first;
    first = second;
    second = tmp;
   }
  }
  public static void Add(ref int first,ref int second)
  {
   first += 1;
   second += 1;
  }
  /// <summary>
  /// 应用程序的主入口点。
  /// </summary>
  [STAThread]
  static void Main(string[] args)
  {
   SortClass.Sort up = new SortClass.Sort(Ascending);//创建代表对象,将类给实例化了,可以认为是实例化了一个指针,得到方法的地址,以下两个相似.该方法的参数必须于Sort所声明的完全一致.
   SortClass.Sort down = new SortClass.Sort(Descending);
   SortClass.Sort add = new SortClass.Sort(Add);

   SortClass doIT = new SortClass();//创建一个对象

   SortClass.val1 = 310;
   SortClass.val2 = 220;

   Console.WriteLine("Before Sort: val1 = {0},val2 = {1}",
       SortClass.val1,SortClass.val2);
   doIT.DoSort(up);//这个对象就调用了这个代表,以下两个也一样.
   Console.WriteLine("After Sort: val1 = {0},val2 = {1}",
       SortClass.val1,SortClass.val2);

   Console.WriteLine("Before Sort: val1 = {0},val2 = {1}",
    SortClass.val1,SortClass.val2);
   doIT.DoSort(down);
   Console.WriteLine("After Sort: val1 = {0},val2 = {1}",
    SortClass.val1,SortClass.val2);

   doIT.DoSort(add);
   Console.WriteLine("After Sort: val1 = {0},val2 = {1}",
    SortClass.val1,SortClass.val2);

  }
 }
}
  这是一个使用代表的简单例子.说白了,也就是像在C里面的设计一个函数,该函数的参数也是一个函数.但是整个过程还是有所不同的.C#是面向对象的.所有的东西都要用类的思想来看它.在则,代表跟接口有点相似,只不过它定义的是所要采取的方法和具体参数.但是接口没有.有一个共同点就是形式必须匹配,

using System;

namespace event1
{
 delegate void CharEventHandler(object source,CharEventArgs e);//创建事件代表,第二个参数必须是EventArgs继承过来的.上面那个代表的参数是两个整数,而这里是两个用户自定义的对象.(为事件建立代表)
 
 public class CharEventArgs : EventArgs//包含事件处理程序可以使用的数据
 {         //EventArgs类用于将数据传给事件处理程序(创建一个类来给事件处理程序传递参数).
  public char CurrChar;
  public CharEventArgs(char CurrChar)//构造函数
  {
   this.CurrChar = CurrChar;
  }
 }

 class CharChecker//创建一个引发事件的类,这个类包含在条件满足时引发事件的代码.(使事件发生)
 {
  char curr_char;
  public event CharEventHandler TestChar;//事件的声明,TestChar用于给代表指定方法以及执行方法
  public char Curr_Char                  
  {
   get { return curr_char;}
   set
   {
    if(TestChar != null)//当没有对应的事件处理程序时这个值就为NULL,因为它是一个事件对象.
    {
     CharEventArgs args = new CharEventArgs(value);
     TestChar(this,args);//调用代表
     curr_char = args.CurrChar;
    }
   }
  }
 }
 /// <summary>
 /// Class1 的摘要说明。
 /// </summary>
 class Class1
 {
  /// <summary>
  /// 应用程序的主入口点。
  /// </summary>
  [STAThread]
  static void Main(string[] args)
  {
   CharChecker tester = new CharChecker();
   //将事件处理程序和该对象关联起来
   tester.TestChar += new CharEventHandler(Drop_A);

   tester.Curr_Char = 'B';//使事件发生
   Console.WriteLine("{0}",tester.Curr_Char);

   tester.Curr_Char = 'r';
   Console.WriteLine("{0}",tester.Curr_Char);

   tester.Curr_Char = 'a';
   Console.WriteLine("{0}",tester.Curr_Char);

   tester.Curr_Char = 'd';
   Console.WriteLine("{0}",tester.Curr_Char);

  }

  static void Drop_A(object source,CharEventArgs e)//事件处理程序
  {
   if(e.CurrChar == 'a' || e.CurrChar == 'A')//声明事件对应的代码.
   {
    Console.WriteLine("Don't like 'a'!");
    e.CurrChar = 'X';
   }
  }//该处理程序接受一个CharEventArgs参数.然后从该对象中取出CurrChar的值
 } //并对其进行检查,作出相应处理 
}

暂时就这么理解,还真有点搞不清楚.要理解事件,就要先理解代表的作用,这个是关键.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值