C#委托与事件的学习

以前做的东西没用到过委托事件(web开发),没发现具体有什么用。昨天老师讲委托事件那叫一个水啊,基本上就是说了语法就算了,回来自己找了文章学习了一下,主要就是张子阳的…(张子阳的委托事件文章)。确实对委托事件有了一定的理解,自己写个小程序练习下。

首先模拟WinForm中按钮点击事件,当然我不知道WinForm中是怎么实现按钮的点击事件的,首先实现处理窗体上按钮事件的类,根据点击的不同类型选择不同类型的方法处理:

 class Click
{
public void ChoiceFunction(string clickWay)
{
switch (clickWay)
{
case "单击":
OnlyClick oc = new OnlyClick();
oc.OnlyClicked(clickWay);
break;
case "双击":
DoubleClick dc = new DoubleClick();
dc.DoubleClicked(clickWay);
break;
}
}
}

接着是单击事件的处理类:

//处理单击
class OnlyClick
{
public void OnlyClicked(string clickWay)
{
Console.WriteLine("您的操作时{0}", clickWay);
}
}

双击事件类似,略......。

接着在客户端也就是Main()中做我们的操作

class Program
{
static void Main(string[] args)
{
Click cl = new Click();
Console.WriteLine("**********单击按钮**********");
cl.ChoiceFunction("单击");
Console.WriteLine("**********单击按钮**********");
cl.ChoiceFunction("双击");

}
}

当然会输出如我们预料的结果。

可以看到程序的可扩展性事相当差的,如果我们想给按钮添加别是事件怎么办,继续写新的类,加更长的switch进行选择,此时委托的好处就出来了,我们可以把方法当参数传递给点击处理类,你单击就传入单击的处理方法,双击就传入双击的处理方法,再有新的功能只要写新的类就行。委托类似于C里的函数指针,把可以把方法当参数传递,接着改造上面的程序。

首先声明委托:

public delegate void ClickDelegate(string clickWay);//定义委托

接着对Click类进行改造:

class Click
{

public void ChoiceFunction(string clickWay,ClickDelegate clickFunction)
{
clickFunction(clickWay);
}
}

剩下的就是在客户端给Click传递要处理点击事件的方法了:

class Program
{
static void Main(string[] args)
{
Click cl = new Click();
OnlyClick oc=new OnlyClick();
DoubleClick dc=new DoubleClick();
Console.WriteLine("*********单击*********");
cl.ChoiceFunction("单击", new ClickDelegate(oc.OnlyClicked));//把处理单击事件的方法传递给委托
Console.WriteLine("*********双击*********");
cl.ChoiceFunction("单击", new ClickDelegate(dc.DoubleClicked));//把处理双击事件的方法传递给委托
}
}

处理单击事件的类和处理双击事件的类不用动,运行依然是我们要的结果:

这里就可以看到委托的灵活性了,我们可以很方便的给程序添加新的功能,而不必担心要进行过大的改动。

但是看到我们定义的委托在整个命名空间下,范围这么大,不符合面向对象封装的思想,所以我想把它拿到Click类里面,不过如果把委托拿到了Clickl里面,在外面我们就没办法用了,也没办法给Click传递方法了。接着event就出现了,此时事件event就好像我们在类里定义的属性一样 ,供外部访问委托。接着我们继续改造程序,首先把委托拿到Click类里面,然后定义事件:

//点击的处理
class Click
{
public delegate void ClickDelegate(string clickWay);//定义委托
public event ClickDelegate ClickEvent;//定义事件
public void ChoiceFunction(string clickWay)
{
if (ClickEvent != null)
{
ClickEvent(clickWay);
}
}
}

其中的ChoiceFunction用于触发事件,然后在客户端,注册事件就好了。

class Program
{
static void Main(string[] args)
{
Click cl = new Click();
OnlyClick oc = new OnlyClick();
DoubleClick dc = new DoubleClick();
Console.WriteLine("*********单击*********");
cl.ClickEvent += oc.OnlyClicked;//注册单击事件
cl.ChoiceFunction("单击");
Console.WriteLine("*********双击*********");
cl.ClickEvent -= oc.OnlyClicked;//取消单击事件的注册
cl.ClickEvent += dc.DoubleClicked;//注册双击事件
cl.ChoiceFunction("双击");
}
}

输出结果依然如故。Click就充当了事件的发布者,而OnlyClick,DoubleClick就充当了事件的注册者。其中事件是否要发生的决定权在Click中,外面的只要注册了事件就好,当调用了触发事件的方法时cl.ChoiceFunction(),

就触发了事件,相应的事件处理方法就会得到执行。虽然在Click中把委托定义是public但在外面根本没法访问,在声明委托相关的事件后,会隐式的创建一个委托的实例,是私有的,所以这就对委托进行了封装。

当然委托事件根本没这么简单,自己的理解还不够....








 




原文地址:https://www.cnblogs.com/yyzq/p/2357251.html