Delegate的概念
Delegate 类似于C或者C++中的指针(本人十分讨厌这句话,因为本人跟C++和C不是很熟,让自己更晕).使用Delegate我们可以封装一个方法的引用.这样我们就可以通过委托去调用我们封装的方法,而不需要知道我们具体调用了哪个方法.
很多人像我一样会问到,不使用delegate我一样可以达到同样的效果,我为什么要使用委托?OK这个问题,我也问了自己很多次了.我通过下面的这个实例来回答这个问题.
直接调用(不使用delegate)
using System;
using System.Collections.Generic;
using System.Text;
namespace EventAndDelegate
{
public class DelegateTest
{
public void Process()
{
Console.WriteLine("Process() begin");
Console.WriteLine("Process() end");
}
}
class Program
{
static void Main(string[] args)
{
DelegateTest myDelegate = new DelegateTest();
myDelegate.Process();
}
}
}
上面的这段代码运行的很好.但是如果我们需要在某些情况下才去Call Process()这个方法的时候,我们需要怎么样去做呢?比如我们在A(),B()方法中都需要调用这个Process()方法,你可能能想到的办法是 分别在A(),B()中分别实例化DelegateTest类,然后都执行myDelegate.Process();
class Program
{
static void Main(string[] args)
{
DelegateTest myDelegate = new DelegateTest();
myDelegate.Process();
//Call A
A();
//Call A
B();
}
static void A()
{
DelegateTest myDelegate = new DelegateTest();
myDelegate.Process();
}
static void B()
{
DelegateTest myDelegate = new DelegateTest();
myDelegate.Process();
}
}
这样是不是很麻烦?当然了.有没有更好的方法呢.这个时候委托就显的很重要了.我们可以把委托当作参数传递过去.就直接可以调用了
我们直接看下代码
using System;
using System.Collections.Generic;
using System.Text;
namespace EventAndDelegate
{
delegate void DelegateExample();
public class DelegateTest
{
public void Process()
{
Console.WriteLine("Process() begin");
Console.WriteLine("Process() end");
}
}
class Program
{
static void Main(string[] args)
{
DelegateTest myDelegate = new DelegateTest();
//封装Process方法
DelegateExample delegateEx = new DelegateExample(myDelegate.Process);
//Call A
A(delegateEx);
//Call A
B(delegateEx);
}
static void A(DelegateExample myDelegate)
{
myDelegate();
}
static void B(DelegateExample myDelegate)
{
myDelegate();
}
}
}
当然委托的好处很多,我这里只是抛砖引玉而已.
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(40, 12);
}
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()方法进行响应.通过事件和委托,我们可以让程序自动的去做事!
这就是委托和事件的完整的应用实例!
| 作者:不懂.NET |
| 出处:http://mqsuper.cnblogs.com | |
| 本文版权所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 |
本文详细介绍了 C# 中的委托和事件概念,通过实例解释了如何使用委托封装方法并传递,以及如何定义和触发事件。适用于 C# 初学者。


715

被折叠的 条评论
为什么被折叠?



