C#事件(event)解析

事件(event)

  事件类似于异常,因为它们都是由对象引发(抛出),我们可以提供代码来处理事件。但它们也有区别,最重要的区别是并没有与try...catch 类似的结构来处理事件,而必须订阅(subscribe)它们。订阅一个事件的含义是:提供代码,并在事件发生时执行这些代码,它们称之为事件处理程序。在实际编程中,就会有三个对象参与整个活动:(1)事件发生者(2)事件处理者(3)除此之外还有它们的活动平台。事件发生者触发了一个事件,但它并不知道哪个对象或方法将会接受到并处理它触发的事件,它对事件处理的唯一要求就是:通过委托指明处理事件的方法必须有的返回类型和参数。委托是双方的一个桥梁,即.NET Framework中就是委托(delegate)。

我们可以用一个恐怖分子(肇事者)和安全部门的比喻,来说明事件和委托的大概意思,如果不当,请各位拍砖。

1、首先创建一个自己的EventArgs类。
引自MSDN:
EventArgs是包含事件数据的类的基类,此类不包含事件数据,当事件引发不需要向事件处理程序传递状态信息会使用此类;如果事件处理程序需要状态信息,则应用程序必须从此类派生一个类来保存数据。

作案信息使用按键来模拟:派生一个CrimeEventArgs类

// -------------------作案信息
internal   class  CrimeEventArgs: EventArgs
{
    
private char keyChar;
    
public CrimeEventArgschar keyChar ) : base()
    
{
        
this.keyChar = keyChar;
    }


    
public char KeyChar
    
{
        
get
        
{
            
return keyChar;
        }

    }

}


2、再创建一个事件发生者,即肇事者的类Culprit

// -------------------Culprit是肇事者
internal   class  Culprit
{
    
// 创建一个委托,返回类型为void,两个参数-------------------(1)肇事后果,安全部门会启动的应急方案
    public delegate void CrimeHandler( object sender, CrimeEventArgs e );
    
// 将创建的委托和特定事件关联,在这里特定的事件为KeyDown----(2)肇事事件,即炸弹、火灾等
    public event CrimeHandler Crime;
    // 需要一个过程才能够激发事件,----------------------------(3)肇事活动,实施过程Run()
    
public void Run()
    
{
        
bool finished = false;
        
do
        
{
            Console.WriteLine( 
"Input a char" );
            
string response = Console.ReadLine();

            
char responseChar = ( response == "" ) ? ' ' : char.ToUpper( response[0] );
            
switch( responseChar )
            
{
                
case 'X':
                    finished 
= true;
                    
break;
                
default:
                    
// 得到按键信息的参数
                    CrimeEventArgs keyEventArgs = new CrimeEventArgs( responseChar );
                    
// 触发事件-----------------------------------(4)留下了蛛丝马迹
                    CrimethisCrimeEventArgs);
                    
break;
            }

        }
while!finished );
    }

}


这里注意Crime( this,CrimeEventArgs);一句,这就是触发事件的语句,并将事件交由
CrimeHandler这个委托来处理,委托指定事件处理方法去处理事件,这就是事件接收方的类的事情了。参数this是指触发事件的对象就是本身这个对象,CrimeEventArgs包含了按键信息。

3、最后创建一个事件接收方的类,这个类先产生一个委托实例,再把这个委托实例添加到产生事件对象的事件列表中去,这个过程又叫订阅事件。然后提供一个方法回显按键信息。

// -------------------SecurityDepartment是安全部门
internal   class  SecurityDepartment
{
    
public SecurityDepartmentCulprit culpritor )----------(5)安全部门天生就是对付肇事者的,所以用肇事者对象构造安全部门
    
{
        
// 产生一个委托实例并添加到KeyInputMonitor产生的事件列表中---(6)时刻准备应付肇事事件,已经准备好相应的应急方案。
        culpritor.Crime+= new culpritor.CrimeHandlerthis.OnCrime);
    }

    
private void OnCrime(object sender, CrimeEventArgs e)
    
{
        
// 真正的事件处理函数
        Console.WriteLine( "Capture key: {0}", e.KeyChar );
    }

}


4、看一下如何调用


// -------------------USA是现实世界;这个世界就是这样,正义双方的对决正在上演......
public   class  USA
{
    
public static void Main()
    
{
        
// 实例化一个恐怖分子------------(7)肇事者开始出现
        Culprit laddon = new Culprit();
        
// 实例化一个安全部门------------(8)安全部门开始关注
        SecurityDepartment FBI = new SecurityDepartmentladdon );
        
// 运行------------(9)看不见的对决已经展开
        laddon.Run();
    }

}


参考自 博客园http://www.cnblogs.com/michaelxu/archive/2008/04/02/1134217.html



以下内容参考自:http://www.bubuko.com/infodetail-1413598.html

C# 事件与委托的区别

先看一段程序



  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. Test obj = new Test();
  6. obj.print += printout1; //绑定printout1方法
  7. obj.print += printout2; //绑定printout2方法
  8. obj.start();
  9. }
  10. static void printout1()
  11. {
  12. Console.WriteLine("输出第一段字符串");
  13. }
  14. static void printout2()
  15. {
  16. Console.WriteLine("输出第二段字符串");
  17. }
  18. }
  19. public delegate void Print();//创建委托
  20. class Test
  21. {
  22. public event Print print;//创建事件实例
  23. public void start()
  24. {
  25. print();//触发事件
  26. }
  27. }

上面的代码使用的是标准的事件委托格式,现在我将其中的event关键字去掉,你会发现程序依然可以正常的运行,不会出现任何的问题。

技术分享

事件实际上是一个特殊的委托实例,不用事件也没有关系。实际上事件只是削弱了委托的功能,event在编译器角度保护了你程序安全,因为你只能使用+=、-= 来注册事件了,而不能使用 = 为事件关联方法。(在委托中还可以使用=来绑定方法,不过=是一种破坏性代码,不管之前是否已经绑定的有方法了,他都会将其清除)

例子:将上面的代码为事件绑定方法的部分中的 += 换成 = 编译器就会报错

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. Test obj = new Test();
  6. obj.print = printout1;//绑定printout1方法时出错
  7. obj.start();//事件不能使用等号运算符绑定方法
  8. }
  9. static void printout1()
  10. {
  11. Console.WriteLine("输出第一段字符串");
  12. }
  13. }
  14. public delegate void Print();//创建委托
  15. class Test
  16. {
  17. public event Print print;//创建事件实例
  18. public void start()
  19. {
  20. print();//触发事件
  21. }
  22. }
技术分享 错误提示







你可能感兴趣的:(C#)