代理
C#:代理[代表、委托]是对方法的引用,指向的是方法,c#中以类的形式对代理进行了实现,设置相应关键字
代理类型是某个方法的类型或者方法标识
代理的属性:
- 代理所指向方法的标识
- 代理能够指向[某个方法的]代理[的引用]
- 指向某个实际的方法
方法标识:方法的返回类型和方法的参数类型
使用delegate关键词声明一种类型的代理
代理引用的使用
可以使用|该代理类型的引用|指向[调用]|符合[代理所定义的]标识|的实际方法
具体过程就是将标识相同的方法名作为参数[通过]相应的代理传递给类型代理的引用
//声明使用的命名空间
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace collection
{//定义program类
class program
{
//定义MyDelegate代理:定义了一个新的代理相当于创建了System.Delegate类的一个子类,所以不能某个方法[^2]的内部定义代理
delegate int MyDelegate(int p,int q);
//定义符合MyDelegate标识类型的方法,
//static函数
static int Add(int a, int b)
{
return a + b;
}
static void Main()
{adMyDelegate代理引用指向Add方法1
MyDelegate adMyDelegate =null;
adMyDelegate = new MyDelegate(Add);
int r = adMyDelegate(3, 4);
//adMyDelegate代理引用指向Add方法2
MyDelegate adMyDelegate =new MyDelegate(Add);
//调用
int r=adMyDelegate(2,3);
}
}
}
代理作为方法的参数
通过将代理作为参数传递给方法
delegate int MyDelegate(int p,int q);
static void PerformOperation(int p,int q, MyDelegate Operation)
{
int a=Operation(int p,int q);
}
.NET Framework中的代理
在.NET中代理更多表现为引用,所有代理都继承 System.Delegate 类,一个代理其实是|继承System.Delegate 类后|形成了新的|引用类型,使用该类型的实例可以调用|与代理定义|方法标识|吻合的方法.定义了一个新的代理相当于创建了System.Delegate类的一个子类,所以不能某个方法1的内部定义代理
多重代理
- 一个代理同时指向多个符合方法标识的方法,多重代理调用后,该代理指向的所有方法都被调用
- 是.NET代理的特点,使程序在设计时更加方便灵活
- 是.NET代理的特点,使程序在设计时更加方便灵活
- 本质:是对System.MulticastDelegate类的继承和实现,也是System.Delegate子类
- 局限:所定义的方法标识的返回值必为void类型2
- 事件的处理方法就是通过多重代理实现的
使用
//定义多重代理
delegate void MyMulticastDelegate(int p, int q);
多重代理引用多于一个方式时,使用+=添加新方法,使用-=移除方法。【程序设计时可以将功能分解,通过代理调用】
static void Main()
{
MyMulticastDelegate hhh = null;
hhh = new MyMulticastDelegate(Add);
//多重代理引用多于一个方式时,使用+=添加新方法
hhh += new MyMulticastDelegate(Max);
}
//声明使用的命名空间
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace collection
{//定义program类
class program
{
//定义多重代理
delegate void MyMulticastDelegate(int p, int q);
static void Add(int a, int b)
{
Console.WriteLine( a + b);
}
static void Max(int a, int b)
{
Console.WriteLine(a > b ? a : b);
}
static void Main()
{
//多重代理
MyMulticastDelegate hhh = null;
hhh = new MyMulticastDelegate(Add);
//多重代理引用多于一个方式时,使用+=添加新方法
hhh += new MyMulticastDelegate(Max);
//调用
hhh(3, 4);
Console.ReadLine();
}
}
}
事件
所有程序需要响应处理的动作。事件机制是以消息为基础的,当特定动作产生后会发出相应的消息,关注该事件的应用程序收到事件发出的消息会执行相应程序。
事件的触发类:产生事件的类
事件的接受类:处理事件的类
事件的处理方法:处理事件的方法
C#中的事件处理
通过类的形式实现的,且是C#中的一个基础类,可以使用event关键字定义一个事件,事件的实现和处理的步骤如下:
-
在所有类的外部为事件定义一个公共访问类型的多重代理
public delegate void EventDelegate(object sender,EventArgs s);
-
定义一个可以触发类,在内部使用event关键字与之前声明的代理共同定义一个公共访问类型的事件。在内部设计一个事件产生的逻辑(方法)[当特定的|动作发生或消息到达,会触发事件]。事件的第一个参数是触发类,第二个参数是传给事件处理方法的信息。
public event EventDelegate MyEvent; SomeEventArgs someData=newSomeEventArgs(/*必要的参数信息*/); MyEvent(this,someData); //一个事件发生后,不需要向事件处理方法传递参数,则定义事件的产生如下 MyEvent(this,null);
-
定义一个事件的接受类,在其中定义一个事件的处理方法。这个处理方法必须符合1中代理定义的方法标识,通常情况下,会以“On”作为方法名字的起始字符。在接受类中实例化2中定义的类,并将处理方法与其绑定(即将触发类中的代理指向事件的处理方法)。
//声明使用的命名空间
using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Event
{
//在所有类的外部为事件定义一个公共访问类型的多重代理,定义事件的代理
public delegate void TimerEvent(object sender,EventArgs s);
class Timer
{
//在内部使用event关键字与之前声明的代理共同定义一个公共访问类型的事件
public event TimerEvent Timerd;
public void Start()
{
for (int i = 0; i < 5; i++)
{
//事件
Timerd(this,null);
Thread.Sleep(1000);
}
}
}
class Sample
{
//加静态关键字
static void Main()
{
//实例化2中的定义的类
Timer clocker = new Timer();
//将触发类中的代理指向事件的处理方法,执行顺序与添加顺序一致
clocker.Timerd += new TimerEvent(Onclock);
clocker.Timerd += new TimerEvent(Onclock2);
clocker.Start();
Console.ReadLine();
}
// 加静态关键字 定义一个事件的处理方法。这个处理方法**必须符合1中代理定义的方法标识**
static public void Onclock(object sender, EventArgs s)
{
Console.WriteLine("收到时钟事件");
}
static public void Onclock2(object sender, EventArgs s)
{
Console.WriteLine("Come On");
}
}
}
利用事件传递数据
- 定义一个System.EventArgs类的子类
- 在类中封装要传递给方法的数据,可以定义为成员变量或者类的属性
- 触发类中实例化该子类,通过事件传递给相应方法
//声明使用的命名空间
using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Event
{
//在所有类的外部为事件定义一个公共访问类型的多重代理
public delegate void TimerEvent(object sender, ClockEventArgs s);
class Timer
{
//在内部使用event关键字与之前声明的代理共同定义一个公共访问类型的事件
public event TimerEvent Timerd;
public void Start()
{
for (int i = 0; i < 5; i++)
{
//事件
//实例化子类 new ClockEventArgs(i+1)
Timerd(this, new ClockEventArgs(i+1));
Thread.Sleep(1000);
}
}
}
//定义传递数据的子类
public class ClockEventArgs : EventArgs
{
private int TimerCount;
public ClockEventArgs(int TimerCount)
{
this.TimerCount = TimerCount;
}
public int Count
{
get
{
return TimerCount;
}
}
}
class Sample
{
//加静态关键字
static void Main()
{
//实例化2中的定义的类
Timer clocker = new Timer();
//将触发类中的代理指向事件的处理方法
clocker.Timerd += new TimerEvent(Onclock);
clocker.Start();
Console.ReadLine();
}
// 加静态关键字 定义一个事件的处理方法。这个处理方法**必须符合1中代理定义的方法标识**
static public void Onclock(object sender, ClockEventArgs s)
{
Console.WriteLine("第{0}次收到时钟事件",s.Count);
}
}
}