要了解事件,必须先了解委托
https://blog.csdn.net/XiuGaiZhong/article/details/106115407
事件就是委托的实例,怎么理解?首先我们声明一个委托
public delegate void Remainder(int num);
然后实例化一个该委托
Remainder remainder = new Remainder(RemainderLogic);
这里的remainder就是委托的实例,而假如我声明一个事件,
public event Remainder remainderEvent;
这里的remainderEvent和上面的remainder基本上就是一个意思
在使用事件前一定要先声明委托
事件也可以被+=来被传递方法
但是既然说是基本上是一个意思,那肯定就有什么地方不同.
事件可以限制变量被外部调用,就是说,哪个类声明他的哪个类就调用他.
也就是说,比起直接实例化一个委托,声明一个事件更加安全.
下面来例子
文件一Method.cs
static class Method
{
public static int Plus(int a, int b)
{
return a + b;
}
public static int Subtract(int a, int b)
{
return a - b;
}
public static int Multiply(int a, int b)
{
return a * b;
}
public static int Divide(int a, int b)
{
return a / b;
}
}
这里面有一堆方法有关于两个数字加减乘除,这是我认为最好理解的类,因为这里只存放运算逻辑.
文件二Program.cs
namespace CSharplearn
{
class Program
{
static void Main(string[] args)
{
Trigger trigger = new Trigger();
trigger.TrigPrinter(9, 7, 3);
}
}
}
这Main函数所在的类,它实例化了trigger类并调用了里面的方法,trigger类里有什么,我们来看看
文件三Trigger.cs
class Trigger
{
public void TrigPrinter(int a,int b,int mode)
{
IsEven isEven = new IsEven();
switch (mode)
{
case 1:
isEven.CalculationEvent += Method.Plus;
isEven.IsEvenMethod(a, b);
break;
case 2:
isEven.CalculationEvent += Method.Subtract;
isEven.IsEvenMethod(a, b);
break;
case 3:
isEven.CalculationEvent += Method.Multiply;
isEven.IsEvenMethod(a, b);
break;
default:
isEven.CalculationEvent += Method.Divide;
isEven.IsEvenMethod(a, b);
break;
}
}
}
Trigger类里面有一个方法TrigPrinter,我定义了三个参数,a,b代表要被处理,mode代表选择的处理方式或者说处理逻辑.例如mode等于1时,他就会给IsEven类里的事件传递加法逻辑然后调用IsEvenMethod来处理a,b.我们最后来看IsEven类是什么样的.
文件四IsEven.cs
using System;
class IsEven
{
public delegate int Calculation(int a, int b);
public event Calculation CalculationEvent;
public void IsEvenMethod(int a,int b)
{
int detectValue = CalculationEvent(a,b);
bool result;
result = detectValue % 2 == 0;
if (result)
{
Console.WriteLine("这个数字是个整数");
}
else
{
Console.WriteLine("这个数字不是整数");
}
}
}
IsEven类里有一个委托,该委托类型的事件和一个方法.这个方法会根据调用事件里的方法来运算a,b,然后再把结果进行一个整数检测得出一个布尔值,最后根据布尔值来打印他是否是整数.
所以整个程序的逻辑是,Main方法里调用TrigPrinter,TrigPrinter把逻辑和数据传到IsEven里最后调用类里的方法来得出结果.
结果:
9*7=63不是整数,结果正确.
事件其实改变的是对程序设计的方式.例如,当用户干什么的时候,给事件A绑上xx方法并执行里面的方法,事件A里面可以套事件B,再套事件C,无限套娃.事件就相当于一个触发器,当怎么样的时候就执行什么.
EventHandler
有些时候我们想直接用事件且懒得去声明委托,这时候微软给我提供了一个委托叫EventHandler,主要是给事件服务的.
EventHandler的委托是这样的
public delegate void EventHandler(object sender, EventArgs e);
它还有一个泛型兄弟长这样
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
声明一个EventHandler类的事件是这样的
public event EventHandler 我是事件名;
首先来解释这两个参数是什么意思
第一个object sender,意思是调用什么东西,例如我调用了上面 我是事件名 这个事件,但是这个事件也可以去调用其他奇奇怪怪的东西,我要让他调用 我是事件名 他自己那么第一个参数就写this
第二个EventArgs,Args是Arguments的缩写,EventArgs的字面意思就是事件参数.EventArgs就是一个我们可以自定义的参数,不过光从字面意思很难理解它,在这个地方可以先记住如果我们创建的事件不需要参数那么就不需要EventArgs,第二个参数填EventArgs.Empty,就是空.
注意传给该类事件的方法也必须要有这两个参数,但是你可以定义这两个参数然后不用他们.
using System;
namespace CSharplearn
{
class Program
{
static void Main(string[] args)
{
Trigger trigger = new Trigger();
trigger.TrigMethod();
}
}
class Trigger
{
public event EventHandler TrigEvent;
public void TrigMethod()
{
TrigEvent += Logic.Printer;
TrigEvent(this,EventArgs.Empty);
}
}
class Logic
{
public static void Printer(object sender,EventArgs e)
{
Console.WriteLine("Hello World");
}
}
}
注意Printer方法有这两个参数但是其实这两个参数就是为了配合事件的.
这就是EventHandler的无参用法
但假如我们现在要定义一个有参的EventHandler该怎么做?这时候就要用到EventArgs了.
所以到底怎么用呢,我们可以写一个继承于EventArgs的类(EvenrArgs是所有事件数据的基类),类里面放上我们要用到的参数,然后用EventHandler的泛型兄弟.在泛型的<>里填上我们自己写的类,这样第二个参数因为泛型的关系就变成了我们写的那个类,等同于自定义参数的效果.
using System;
namespace CSharplearn
{
class Program
{
static void Main(string[] args)
{
Trigger trigger = new Trigger();
trigger.TrigMethod();
}
}
class Trigger
{
public event EventHandler<MyEventArgs> TrigEvent;
public void TrigMethod()
{
MyEventArgs myArgs = new MyEventArgs();
myArgs.String = "Hello Space";
TrigEvent += Logic.Printer;
TrigEvent(this, myArgs);
}
}
class Logic
{
public static void Printer(object sender,MyEventArgs e)
{
Console.WriteLine(e.String);
}
}
public class MyEventArgs : EventArgs
{
public string String;
}
}
这就是有参版本的EventHandler,注意Printer方法里的类型,泛型都变成了MyEventArgs