委托:只是一个类型,当你创建一个变量,那他创建时的函数指定的方法名,必须和委托的参数一样:
关键字:delegate
委托
(1) 声明委托
C#使用关键字delegate来声明委托类型,具体格式如下:
[访问修饰符] delegate 结果类型 委托标识符([形参列表]);
委托类型可以在声明类的任何地方声明。
(2) 实例化委托
委托使用new运算符来实例化且新创建的委托实例所引用的对象为以下情形之一:
- 委托创建表达式中引用的静态方法
- 委托创建表达式中引用的目标对象(此对象不能为null)和实例方法
- 另一个委托
(3) 使用委托
实例化一个委托后,可以通过委托对象的名称及放入括号的要传递给委托的参数来调用委托对象。调用委托时,调用表达式的主表达式必须是委托类型的值。参考示例代码,理解委托
public delegate void MyDelegateNoParam();//这里就声明了一个无参数方法委托器
MyDelegateNoParam myDelegateNoParam = new MyDelegateNoParam(Test);//这里就创建了一个无参数方法委托器
void Test()//这里注意Test的参数,与MyDelegateNoParam()一样,无参数即可。
{
MessageBox.Show("This is Test Method.");
}
看到这里,你已经对委托的声明,创建有了了解。上面是无参数的方法处理。
下面是有参数的代码:
public delegate void MyDelegateHaveParam(string content);//这里就声明了一个带一个参数方法委托器
MyDelegateHaveParam myDelegateHaveParam = new MyDelegateHaveParam(Test);//这里就创建了一个带一个参数方法委托器
void Test(string content)//这里注意Test的参数,与MyDelegateHaveParam()一样,参数与委托声明一样即可。
{
MessageBox.Show(content);
}
但委托的方法怎么调用则需要通过事件来实现
事件:其实就是执行已绑定的委托方法的一个对象,当然,未创建对象前,他只是一个类型。
事件的声明
事件的声明分为两种,声明事件域的格式如下:
[事件修饰符] event 事件类型 事件名;
声明事件属性的格式如下:
[事件修饰符] event 事件类型 事件名{访问符};
其中事件修饰符就是以前常提到的访问修饰符,如:new、public、protected、internal、private、static。事件所声明的类型(type)则必须是一个代表delegate类型。而此代表类型应预先声明如:
public delegate void EventHandler
关键字:event
public event MyDelegateNoParam MyNoParamDelegateHandler;//这里就声明了一个MyDelegateNoParam 类型的事件。
public event MyDelegateHaveParam MyHaveParamDelegateHandler;//这里就声明了一个MyDelegateHaveParam 类型的事件。
使用:
priavte void ActionNoParamDelegateByEvent()//事件执行无参数委托方法一个的DEMO { if(MyNoParamDelegateHandler!=null)//判断事件有否绑定方法可以判断他是否为null MyNoParamDelegateHandler();//执行 else { MyNoParamDelegateHandler += myDelegateNoParam;//结合委托那里所示,将事件与一个无参数 //注意给事件绑定对应的方法/委托,请使用"+="运算符 MyNoParamDelegateHandler();//执行 } } priavte void ActionHaveParamDelegateByEvent()//事件执行带参数委托方法一个的DEMO { if(MyHaveParamDelegateHandler!=null)//判断事件有否绑定方法可以判断他是否为null MyHaveParamDelegateHandler(); else { MyHaveParamDelegateHandler += myDelegateHaveParam;//结合委托那里所示,将事件与一个带参数 //注意给事件绑定对应的方法/委托,请使用"+="运算符 MyNoParamDelegateHandler();//执行 } }
namespace 派生类TemperatureEventArgs { public class TemperatureEventArgs : EventArgs { private int temperature; public int Temperature { get { return temperature; } } public TemperatureEventArgs(int _temperature) { temperature = _temperature; } } public class EventSender { public delegate void TemperatureEventHander(object sender, TemperatureEventArgs e); public event TemperatureEventHander temperaturePress; protected virtual void OnTemperaturePress(TemperatureEventArgs e) { TemperatureEventHander hander = temperaturePress; if (hander != null) temperaturePress(this, e); } public void isTemperaturePress(int temperature) { OnTemperaturePress(new TemperatureEventArgs(temperature)); } } public class EventReceive { public void Press(object sender, TemperatureEventArgs e) { if (e.Temperature > 80) { Console.WriteLine("报警器检测温度为{0},马上会发生火灾,请速撤离现场", e.Temperature); } else if (e.Temperature > 50 && e.Temperature <= 80) { Console.WriteLine("报警器检测温度太高,可能会发生火灾,请做好撤离现场的准备"); } else { Console.WriteLine("这里温度正常,请安心工作"); } } } class Program { static void Main(string[] args) { bool trueorfalse = true; while (trueorfalse) { Console.WriteLine("请输入检测器温度,(只能输入数字,否则会出现异常):"); int temperature = Convert.ToInt32(Console.ReadLine()); EventSender es = new EventSender(); EventReceive er = new EventReceive(); es.temperaturePress += new EventSender.TemperatureEventHander(er.Press); es.isTemperaturePress(temperature); if (temperature > 200) { trueorfalse = false; } Console.WriteLine("------------------------------------------------------"); Console.WriteLine("------------------------------------------------------"); } Console.WriteLine("================================================================="); Console.WriteLine("由于温度太高报警器已经损坏,程序将在5秒后退出程序"); Console.WriteLine("请等候......"); Console.WriteLine("距系统关闭还有5秒"); System.Threading.Thread.Sleep(1000); Console.WriteLine("离系统关闭还有4秒"); System.Threading.Thread.Sleep(1000); Console.WriteLine("离系统关闭还有3秒"); System.Threading.Thread.Sleep(1000); Console.WriteLine("离系统关闭还有2秒"); System.Threading.Thread.Sleep(1000); Console.WriteLine("离系统关闭还有1秒"); System.Threading.Thread.Sleep(1000); Console.WriteLine("..."); } } }
调试程序会根据不同的温度做出不同的反应。运行结果:
总结与经验:如果一个类中,公开了一个事件,那么是很好的满足外部使用该类时的功能提供,因为有了事件,我只要有一个与该事件类型(即,委托类型)一样的参数的方法,那么就可以用该方法与该事件绑定了。
可以实现该方法实现的功能。