.NET委托和事件
1.什么是委托 通俗的说:委托就是一个能够存储符合某种格式(方法签名)的方法的指针的容器 上传图片:
2.委托语法 准备一个方法:string Hello(string userName){} string Hello2(string userName){} 声明委托类:delegate string DGSayHi(string userName); 创建委托对象:DGSayHi dgSay = new DGSayHi(Hello); 或 DGSsyHi dgSay = Hello; 追加方法:dgSay+=Hello2; 删除方法:dgSay -=Hello2; 调用委托:dgSay("你好");
3.多播委托 通常将包含多个方法指针的委托叫做多播委托 其实每个用户定义的委托类型编译后都是一个继承于多播委托的类,看源码:
上传图片:
4.委托的目的 (1)能将方法作为参数和返回值传递 (2)调用一个委托,执行N个方法(多播委托)
5.委托的缺点 不进行控制的缺点:可以使用Click=null来清除所有注册的事件,可以用Click()来假冒事件的触发。 解决方案,把委托成员做成private的,然后增加AddClickEventHandler、RemoveClickEventHandler两个public方法
6.什么是事件 对委托变量的可访问性进行控制封装 语法:public delegate void DGSayHi(string name); public event DGSayHi dgSay;//创建事件委托(本质还是委托对象) event会自动生成一个private delegate变量和两个函数: add和remove,C#编译器用这两个方法支持+=和-=操作符
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
public delegate void DGEach(int index,object item);
public delegate void DGTest();
internal class Program
{
public static void Test1(DGTest dgTest)
{
dgTest(); //编译后:dgTest.Invoke();
Console.WriteLine("Test1");
}
public static void Test2()
{
Console.WriteLine("Test2");
}
public static void Test3()
{
Console.WriteLine("Test3");
}
/// <summary>
/// 委托当返回值
/// </summary>
/// <param name="strType"></param>
/// <returns></returns>
public static DGTest InvokeTest(string strType)
{
switch (strType)
{
case "2":
return Test2;
case "3":
return Test3;
default:
return Test3;
}
}
/// <summary>
/// 使用委托模仿jQuery each方法
/// </summary>
/// <param name="list"></param>
/// <param name="func"></param>
public static void Each(ArrayList list, DGEach func)
{
for (int i = 0; i < list.Count; i++)
{
func(i, list[i]);
}
}
private static void Main(string[] args)
{
#region 委托当参数
//DGTest dgTest = new DGTest(Test2);//或者 DGTest dgTest = Test2;
//Test1(dgTest);
#endregion
#region 委托当返回值
//DGTest dgTest = InvokeTest("2");
//dgTest();
#endregion
#region 完成 Each方法
//ArrayList list = new ArrayList();
//list.Add("刘德华");
//list.Add("张学友");
//list.Add("郭富城");
//list.Add("黎明");
// Each(list, delegate(int index,object item)
// {
// Console.WriteLine(index+"---------"+item.ToString());
// });
#endregion
#region 事件练习,一个设计模式的题目,说有三个对象,猫,老鼠,人,猫看见了老鼠,老鼠吓跑了,在过程中把人吵醒, 在编程过程中注意新的对象的参与
Cat c = new Cat();
c.Name = "tom";
c.DGRunEventHandler += c_DGRunEventHandler;
c.SeeMouse(c.Name);
#endregion
}
private static void c_DGRunEventHandler(object sender,EventArgs e)
{
Mouse m = new Mouse();
m.Name = "mouse1";
m.DGRunEventHandler += m_DGRunEventHandler;
m.MouseRun(m);
}
private static void m_DGRunEventHandler(object sender, EventArgs e)
{
Person p = new Person();
p.WakeUp(sender);
}
}
public class Cat
{
public event EventHandler DGRunEventHandler;
public void SeeMouse(string name)
{
Console.WriteLine(name+"看见老鼠");
if (DGRunEventHandler != null)
{
DGRunEventHandler(this,new EventArgs());
}
}
public string Name { get; set; }
}
public class Person
{
public void WakeUp(object sender)
{
Console.WriteLine((sender as Mouse).Name+"老鼠跑,人醒了");
}
public string Name { get; set; }
}
public class Mouse
{
public event EventHandler DGRunEventHandler;
public void MouseRun(object sender)
{
Console.WriteLine((sender as Mouse).Name+"老鼠跑");
if (DGRunEventHandler != null)
{
DGRunEventHandler(this, new EventArgs());
}
}
public string Name { get; set; }
}
}