声明委托
委托声明决定了可由该委托引用的方法。委托可指向一个与其具有相同签名的方法。
委托的声明和方法的声明时一样,只不过多了一个delegate修饰符
委托不是方法,而是一种类型
委托是引用类型
如下两种委托限定了回调方法的类型
public delegate int YyDelegate();
public delegate int MyDelegate (string s);
实例化委托
声明委托后,我们可以通过new关键字来创建委托。委托的构造方法中需要填入的是方法的名 ,注意不带有参数:
例如:
delegate void MyDelegate();
MyDelegate mydel = new MyDelegate(Test);
需要回调的方法:
void Test()
{
Console.WriteLine(“nn真帅”);
}
我们还可以直接赋值:
MyDelegate del = Test;
多播委托
委托对象可使用 “+” 运算符进行合并。一个合并委托调用它所合并的两个委托。只有相同类型的委托可被合并。”-” 运算符可用于从合并的委托中移除组件委托。
使用委托的这个有用的特点,您可以创建一个委托被调用时要调用的方法的调用列表。这被称为委托的 多播(multicasting),也叫组播
在生活办公中使用的打印机就是一个多播的一个实例:
例如张三需要打印一个文件,打印耗时5分钟,李四也需要打印一个文件,那么李四只需要向打印机发出打印文件的命令即可,在打印张三的文件结束后,再打印李四的文件。如果李四反悔了,就可以撤销刚才的操作。
事件
事件(Event) 基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些出现,如系统生成的通知。应用程序需要在事件发生时响应事件。例如,中断。事件是用于进程间通信。
声明事件
在类的内部声明事件,首先必须声明该事件的委托类型。
public delegate void BoilerLogHandler(string status);
然后,声明事件本身,使用 event 关键字:
// 基于上面的委托定义事件
public event BoilerLogHandler BoilerEventLog;
使用事件实现观察者模式
发布者
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 事件案例1
{
delegate void MyDelegate(string str);
class Promulgator
{
public event MyDelegate handler;
public void AddEvent(MyDelegate func)
{
handler += func;
}
public void SubEvent(MyDelegate func)
{
handler -= func;
}
public void ExeEvent(string str)
{
if (handler!=null)
{
handler.Invoke(str);
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
订阅者
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 事件案例1
{
class Subscriber
{
private string name;
public Subscriber(string name)
{
this.Name = name;
}
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public void Notice(string str)
{
Console.WriteLine("{0},{1}",Name,str);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
Program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 事件案例1
{
class Program
{
static void Main(string[] args)
{
Promulgator p = new Promulgator();
Subscriber xiaoming = new Subscriber("小明");
p.AddEvent(xiaoming.Notice);
Subscriber wangyao = new Subscriber("王垚");
p.AddEvent(wangyao.Notice);
Subscriber yadong = new Subscriber("亚东");
p.AddEvent(yadong.Notice);
p.ExeEvent("老板来了,各就各位");
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
Lambda表达式
在Framework 2.0 以前,声明委托的唯一方法是通过方法命名,从Framework 2.0 起,系统开始支持匿名方法。
通过匿名方法,可以直接把一段代码绑定给事件,因此减少了实例化委托所需的编码系统开销。
而在 Framework 3.0 开始,Lambda 表达式开始逐渐取代了匿名方法,作为编写内联代码的首选方式。总体来说,Lambda 表达式的作用是为了使用更简单的方式来编写匿名方法,彻底简化委托的使用方式。
Action
常用泛型委托:Action
此委托由系统提供 无需声明
Action 支持0~16个参数,可以按需求任意使用。
public delegate void Action()
public delegate void Action< T1>(T1 obj1)
public delegate void Action< T1,T2> (T1 obj1, T2 obj2)
public delegate void Action< T1,T2,T3> (T1 obj1, T2 obj2,T3 obj3)
…………
public delegate void Action< T1,T2,T3,……,T16> (T1 obj1, T2 obj2,T3 obj3,……,T16 obj16)
static void Main(string[] args)
{
int x = 1000;
Action action = () => x = x + 500;
action.Invoke();
Console.WriteLine("Result is : " + x);
}
static void Main(string[] args)
{
Action<int> action = (x) =>
{
x = x + 500;
Console.WriteLine("Result is : " + x);
};
action.Invoke(1000);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
Func
委托 Func 与 Action 相似,同样支持 0~16 个参数,不同之处在于Func 必须具有返回值
public delegate TResult Func()
public delegate TResult Func
static void Main(string[] args)
{
Func<double, bool, double> func = Account;
double result=func(1000, true);
Console.WriteLine("Result is : "+result);
}
static double Account(double a,bool condition)
{
if (condition)
return a * 1.5;
else
return a * 2;
}
static void Main(string[] args)
{
Func<double, bool, double> func = (a,condition) =>
{
if (condition)
{
return a * 1.5;
}
else
{
return a * 2;
}
};
double result=func(1000, true);
Console.WriteLine("Result is : "+result);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30