直接看代码:
using System;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
Counter c = new Counter(new Random().Next(10));
c.ThresholdReached += c_ThresholdReached;
c.ThresholdReached?.Invoke(null,null);//这里报错是类的事件触发只能在Counter类的内部,外部只能进行绑定或者解绑
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
{
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached);
Environment.Exit(0);
}
}
class Counter
{
private int threshold;
private int total;
public Counter(int passedThreshold)
{
threshold = passedThreshold;
}
public void Add(int x)
{
total += x;
ThresholdReached(null, null);//定义事件的类的内部不仅可以直接执行事件也可以进行事件的绑定与解绑操作
ThresholdReached += c_ThresholdReached;
if (total >= threshold)
{
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
}
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)//触发事件的方法
{
ThresholdReached?.Invoke(this, e);
}
static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
{
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached);
Environment.Exit(0);
}
public event EventHandler<ThresholdReachedEventArgs> ThresholdReached;//定义事件
}
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
//学习记录:
//1 .net提供了现成的委托类型EventHandler及EventHandler<TEventArgs>,我们可以直接拿来定义事件,如果定义的事件没有事件数据,则使用EventHandler,
//否则使用EventHandler<TEventArgs>,注意EventHandler并不是没有EventArgs,而是使用EventArgs基类本身而进行了省略.需要说明的是这两个委托类型
//都不带有返回值,如果需要定义带有返回值的委托类型需要自行定义。
//2.关于EventArgs:表示包含事件数据的类的基类,并提供要用于不包含事件数据的事件的值。包含数据数据时从EventArgs继承并定义自己的业务数据,
//如上ThresholdReachedEventArgs
//3.类定义的事件尽管由public修饰,但类内部及外部的对事件的访问权限是不一样的,外部只能进行绑定(+=)或解绑(-=)操作,
//内部不仅可以直接执行事件也可以进行事件的绑定与解绑操作,
//因此通常会在类的内部再封装一个方法(尽管可以不封装)来触发事件,同时处理一些稳定的业务逻辑.
}