弄清楚Events and Delegates

       对于像我这样的初学者来说,每次看书看到Event 和Delegate的时候,就头脑发昏.往往会跳过这些章节,去阅读其他的章节,因为读这些章节需要很大的勇气,看不懂,太打击自己的学习兴趣.之前已经却步了很多次了.这次真是硬着头皮把她读完,又到Cnblogs上搜索了很多前辈的关于Event and Delegate的文章,才逐渐的有所了解. Delegate and Event是C#中很重要的概念.所以无论如何,作为net程序员,你必须要懂得,在这里我把我所理解的Delegate and Event 记录下来,希望对初学者有所帮助.

      Delegate的概念

      Delegate 类似于C或者C++中的指针(本人十分讨厌这句话,因为本人跟C++和C不是很熟,让自己更晕).使用Delegate我们可以封装一个方法的引用.这样我们就可以通过委托去调用我们封装的方法,而不需要知道我们具体调用了哪个方法.

      很多人像我一样会问到,不使用delegate我一样可以达到同样的效果,我为什么要使用委托?OK这个问题,我也问了自己很多次了.我通过下面的这个实例来回答这个问题.

      直接调用(不使用delegate)

     

Call a Function directly - No Delegate

  上面的这段代码运行的很好.但是如果我们需要在某些情况下才去Call Process()这个方法的时候,我们需要怎么样去做呢?比如我们在A(),B()方法中都需要调用这个Process()方法,你可能能想到的办法是分别在A(),B()中分别实例化DelegateTest类,然后都执行myDelegate.Process();

   

Code

    这样是不是很麻烦?当然了.有没有更好的方法呢.这个时候委托就显的很重要了.我们可以把委托当作参数传递过去.就直接可以调用了

 我们直接看下代码

   

Delegate Code

当然委托的好处很多,我这里只是抛砖引玉而已.

     Events

     了解事件,我们知道Button是个Class,当你单击它的时候,你触发了它的Click()事件,Timer也是个Class,每一秒都在执行Tick事件.

      我们通过一个实例来学习

      首先定一个事件(在定义事件之前必须定一个委托)

     定义委托

      public delegate void NumberReachedEventHandler(object sender,NumberReachedEventArgs e);

     定义事件

      public event NumberReachedEventHandler NumberReached;

      这样我们就准备OK了,来看下具体的Counter类

     

 class Program
    
{
        
static void Main(string[] args)
        
{
            
// //订阅
            Counter counter=new Counter();           
            counter.NumberReached 
+= new NumberReachedEventHandler(oCounter_NumberReached);
            
//触发
            counter.CountTo(4012);
        }

        
private static void oCounter_NumberReached(object sender, NumberReachedEventArgs e)
        
{
            Console.WriteLine(
"Reached: " + e.ReachedNumber.ToString());
        }

    }

    
//声明委托
    public delegate void NumberReachedEventHandler(object sender,
    NumberReachedEventArgs e);
    
    
class Counter
    
{
        
public event NumberReachedEventHandler NumberReached;
        
public void CountTo(int countTo, int reachableNum)
        
{
            
if (countTo < reachableNum)
                
throw new ArgumentException(
                    
"reachableNum should be less than countTo");
            
for (int ctr = 0; ctr <= countTo; ctr++)
            
{
                
if (ctr == reachableNum)
                
{
                    NumberReachedEventArgs e 
= new NumberReachedEventArgs(
                        reachableNum);
                    OnNumberReached(e);
                    
return;
                }

            }

        }

        
protected virtual void OnNumberReached(NumberReachedEventArgs e)
        
{
            
if (NumberReached != null)
            
{
                NumberReached(
this, e);

            }

        }

    }

 

  上面的代码我们可以看出.当达到一定的数字后,就会触发OnNumberReached去触发 NumberReached(this, e)事件,可能有人要问了.为什么不直接调用 NumberReached(this, e).而是通过OnNumberReached 去间接的调用呢?很好的问题,
protected virtual void OnNumberReached(NumberReachedEventArgs e)

     从OnNumberReached 的定义我们知道,protected .所以Counter的子类可以使用它.virtual  Counter的子类可以重写它,这样就可以在OnNumberReached方法中做更多的事.

     在上面的Main()函数中.我们通过委托,在触发counter.NumberReached 事件的时候,程序就会自动的调用oCounter_NumberReached()方法进行响应.通过事件和委托,我们可以让程序自动的去做事!

这就是委托和事件的完整的应用实例!

   示例代码下载

posted @ 2008-08-25 14:36  莫贝特(MBetter)  阅读(2986)  评论(21编辑  收藏  举报