委托就是相同签名(参数)和返回值类型的有序方法列表
delegate void 名(参数);
名 委托变量 =new 名(添加的方法)–也可以不用new,直接方法
组合委托
多播委托(含有多个方法,连续调用)
(带ref引用参数的委托,参数值会被列表里的方法的返回值改变)
匿名方法初始化委托:委托类型 委托变量 =delegate() { PrintMessage();}
匿名方法可以捕获上一级的外部变量
再简化就是Lambda
委托类型 委托变量 =(int x) => { PrintMessage();}
委托类型 委托变量 = x => { return x+1;}
委托类型 委托变量 = x => x+1;
delegate bool Function(int num);
static Function IsEven = delegate (int num) { return num % 2 == 0; };
//或者使用Func类型:static Func<int,bool> IsEven =delegate(int num){....}///int是代表输入的参数类型,bool是代表输出的值类型
事件——被简化的针对特殊用途的委托
public event 委托类型 事件名;(所以事件是成员,而不是类型)
- 触发 raise
- 发布者 publisher
- 订阅者 subscriber
- 事件处理程序 event handler [ EventHandler (object sender,EventArgs e) 是标准预定义类型,经常使用]
sender是触发事件的对象的引用,EventArgs 是保存一些程序的状态信息
说的再多,不如看代码来的实际
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
PlayMusic p = new PlayMusic("mayang");
//先注册事件
p.Delplay += P_Delplay;
}
private static void P_Delplay(object sender, EventArgs e)
{
PlayMusic P = (PlayMusic)sender;
Console.WriteLine(P.Name + "播放完毕");
}
}
class PlayMusic
{
//先注册一个事件
public event EventHandler Delplay;//用eventhandler类-事件响应基类,本质就是一个委托//参数有二
public string Name { get; set; }
public PlayMusic(string name)
{
this.Name = name;
}
public void PlaySong()
{
Console.WriteLine("播放" + this.Name);
Thread.Sleep(3000);
//启动事件,事件就是一个因果关系的联系,你打我我打你
//事件本身就是一个委托(多播委托),为什么不直接用委托呢?
//因为委托不安全,委托就像一个指针,使用没有什么限制,而事件给其中的委托加了一层壳,只有“因”结束才会引发事件
//而且事件只有在类的内部才能调用
if (Delplay != null)
{
EventArgs e = new EventArgs();
Delplay(this, e);
}
}
}
namespace 事件
{
internal class KeyEventArgs : EventArgs
//EventArgs是包含事件数据的类的基类,此类不包含事件数据,在事件引发时不向事件处理程序传递状态信息的事件会使用此类。
//如果事件处理程序需要状态信息,则应用程序必须从此类派生一个类来保存数据。
{
private char keyChar;
public KeyEventArgs(char keyChar) : base()
{
this.keyChar = keyChar;
}
public char KeyChar
{
get
{
return keyChar;
}
}
}
internal class KeyInputMonitor
{
// 创建一个委托,返回类型为void,两个参数
public delegate void KeyDownHandler(object sender, KeyEventArgs e);
// 将创建的委托和特定事件关联,在这里特定的事件为KeyDown
public event KeyDownHandler KeyDown;
public void Run()
{
bool finished = false;
do
{
Console.WriteLine("Input a char");
string response = Console.ReadLine();
char responseChar = (response == "") ? ' ' : char.ToUpper(response[0]);
switch (responseChar)
{
case 'X':
finished = true;
break;
default:
// 得到按键信息的参数
KeyEventArgs keyEventArgs = new KeyEventArgs(responseChar);
// 触发事件,ta的参数和关联的委托要一致
KeyDown(this, keyEventArgs);
//事件交由KeyDownHandler这个委托来处理,委托指定事件处理方法去处理事件,这就是事件接收方的类的事情了
break;
}
} while (!finished);
}
}
internal class EventReceiver
{
public EventReceiver(KeyInputMonitor monitor)
{
// 产生一个委托实例并添加到KeyInputMonitor产生的事件列表中
monitor.KeyDown += new KeyInputMonitor.KeyDownHandler(this.OnKeyDown);
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
// 真正的事件处理函数
Console.WriteLine("Capture key: {0}", e.KeyChar);
}
}
class 事件1
{
static void Main(string[] args)
{
// 实例化一个事件发送器
KeyInputMonitor monitor = new KeyInputMonitor();
// 实例化一个事件接收器
EventReceiver eventReceiver = new EventReceiver(monitor);
// 运行
monitor.Run();
}
}
}
事件访问器:add(+=)和remove(-=)类似属性