C# 中委托和事件的区别
大抵来说,委托是一个类,该类外部保护着一个字段,指向一个办法。事件能够被看作一个委托类型的变量,通过事件注册、勾销多个委托或办法。本篇别离通过委托和事件执行多个办法,从中领会两者的区别。
□ 通过委托执行办法
class Program
{static void Main(string[] args)
{Example example = new Example();
example.Go();
Console.ReadKey();}
}
public class Example
{public delegate void DoSth(string str);
internal void Go()
{
// 申明一个委托变量,并把已知办法作为其构造函数的参数
DoSth d = new DoSth(Print);
string str = "Hello,World";
// 通过委托的静态方法 Invoke 触发委托
d.Invoke(str);
}
void Print(string str)
{Console.WriteLine(str);
}
}
以上,
○ 在 CLR 运行时,委托 DoSth 实际上就一个类,该类有一个参数类型为办法的构造函数,并且提供了一个 Invoke 实例办法,用来触发委托的执行。
○ 委托 DoSth 定义了办法的参数和返回类型
○ 通过委托 DoSth 的构造函数,能够把合乎定义的办法赋值给委托
○ 调用委托的实例办法 Invoke 执行了办法
但,实际上让委托执行办法还有另外一种形式,那就是:委托变量(参数列表)
public class Example
{public delegate void DoSth(object sender, EventArgs e);
internal void Go()
{
// 申明一个委托变量,并把已知办法作为其构造函数的参数
DoSth d = new DoSth(Print);
object sender = 10;
EventArgs e = new EventArgs();
d(sender, e);
}
void Print(object sender, EventArgs e)
{Console.WriteLine(sender);
}
}
以上,
○ 委托 DoSth 的参数列表和办法 Print 的参数列表还是保持一致
○ 委托 DoSth 中的参数 object sender 通常用来示意动作的发起者,EventArgs e 用来示意动作所带的参数。
而实际上,委托变量(参数列表),事件就是采纳这种模式执行办法的。
□ 通过事件执行办法
public class Example
{public delegate void DoSth(object sender, EventArgs e);
public event DoSth myDoSth;
internal void Go()
{
// 申明一个委托变量,并把已知办法作为其构造函数的参数
DoSth d = new DoSth(Print);
object sender = 10;
EventArgs e = new EventArgs();
myDoSth += new DoSth(d);
myDoSth(sender, e);
}
void Print(object sender, EventArgs e)
{Console.WriteLine(sender);
}
}
以上,
○ 申明了事件 myDoSth, 事件的类型是 DoSth 这个委托
○ 通过 += 为事件注册委托
○ 通过 DoSth 委托的构造函数为事件注册委托实例
○ 采纳委托变量(参数列表) 这种模式,让事件执行办法
而且,通过 += 还能够为事件注册多个委托。
public class Example
{public delegate void DoSth(object sender, EventArgs e);
public event DoSth myDoSth;
internal void Go()
{
// 申明一个委托变量,并把已知办法作为其构造函数的参数
DoSth d = new DoSth(Print);
DoSth d1 = new DoSth(Say);
object sender = 10;
EventArgs e = new EventArgs();
// 为事件注册多个委托
myDoSth += new DoSth(d);
myDoSth += new DoSth(d1);
myDoSth(sender, e);
}
void Print(object sender, EventArgs e)
{Console.WriteLine(sender);
}
void Say(object sender, EventArgs e)
{Console.WriteLine(sender);
}
}
以上,通过 += 为事件注册 1 个或多个委托实例,实际上,还能够为事件间接注册办法。
public class Example
{public delegate void DoSth(object sender, EventArgs e);
public event DoSth myDoSth;
internal void Go()
{
object sender = 10;
EventArgs e = new EventArgs();
// 为事件注册多个委托
myDoSth += Print;
myDoSth += Say;
myDoSth(sender, e);
}
void Print(object sender, EventArgs e)
{Console.WriteLine(sender);
}
void Say(object sender, EventArgs e)
{Console.WriteLine(sender);
}
}
□ 通过 EventHandler 执行办法
先来看 EventHandler 的源代码。
1
可见,EventHandler 就是委托。当初就应用 EventHandler 来执行多个办法。
public class Example
{
public event EventHandler myEvent;
internal void Go()
{
object sender = 10;
EventArgs e = new EventArgs();
// 为事件注册多个委托
myEvent += Print;
myEvent += Say;
myEvent(sender, e);
}
void Print(object sender, EventArgs e)
{Console.WriteLine(sender);
}
void Say(object sender, EventArgs e)
{Console.WriteLine(sender);
}
}
总结:
○ 委托就是一个类,也能够实例化,通过委托的构造函数来把办法赋值给委托实例
○ 触发委托有 2 种形式: 委托实例.Invoke(参数列表),委托实例(参数列表)
○ 事件能够看作是一个委托类型的变量
○ 通过 += 为事件注册多个委托实例或多个办法
○ 通过 -= 为事件登记多个委托实例或多个办法
○ EventHandler 就是一个委托