1.首先给一张图让大家了解什么是委托?它的优缺点是什么?
2.通过代码的运用更深入地了解委托事件(窗体应用程序)
1)下面我们先定义一个无参数的委托。
//1.0 定义一个自定义的委托,此委托的签名是,无返回值void 无参数 public delegate void DmyFirstHander();
2)在需要使用委托的方法块中调用委托。
//1.0 定义一个委托对象,载入实例方法 DmyFirstHander d = new DmyFirstHander(SayHelloCH); //2.0 向委托对象d追加一个方法,+=:其实是给程序员开发方便而产生的语法糖,最终编译器会将语法糖编译成真正的.net代码 //Delegate.Combine() d += Form1.SayHelloEN; d -= SayHelloCH; //缺点:造成委托对象不可控 d = null; //调用委托,d.Invoke(); d();
委托对象载入的实例方法是
void SayHelloCH() { MessageBox.Show("你好呀,小北京"); } static void SayHelloEN() { MessageBox.Show("Hello beijing"); }
3)然后就会得到提示框输出“Hello beijing”
3.下面给一张图让大家了解委托操作代码的本质。
4.一些委托的扩展知识:
1)利用GetInvocationList()获取当前委托对象中的所有方法的单个委托
//利用GetInvocationList()获取当前委托对象中的所有方法的单个委托 Delegate[] darr = d2.GetInvocationList();
2) 遍历所有方法的委托
List<string> reslist = new List<string>(); //遍历所有方法的委托 foreach (Delegate item in darr) { //执行方法委托讲返回结构加入到List<>集合中 reslist.Add((item as DmySecHander).Invoke(100)); //DmySecHander dsH = item as DmySecHander; //dsH(100); }
3)通过string.Join以换行的方式将集合中的所有数据输出到变量res
string res = string.Join(" ", reslist);
4)利用自定义委托处理字符串
public delegate string DProcessString(string str); private void button3_Click(object sender, EventArgs e) { string str = "Hello"; //1.0 对字符串进行转大写处理 MessageBox.Show(ProcessString(str, toupperstr)); //2.0 对str字符串追加一个! MessageBox.Show(ProcessString(str, AddStr)); } string ProcessString(string str, DProcessString dprocessor) { str += "???????"; return dprocessor.Invoke(str); }
string AddStr(string str)
{
return str + "!";
}
string tolowerstr(string str)
{
return str.ToLower();
}
string toupperstr(string str)
{
return str.ToUpper();
}
5)利用系统委托进行排序
private void button4_Click(object sender, EventArgs e) { //对整数进行排序 //int[] arr = { 1, 2, 5, 0 }; //List<int> list = arr.ToList(); ////对list集合进行倒序排列 //list.Sort(Comp); //MessageBox.Show(string.Join(" ", list)); //2.0 对一个字符串进行排序 List<string> slist = new List<string>() { "a", "ab", "abc" }; slist.Sort(Compstring); MessageBox.Show(string.Join(" ", slist)); } /// <summary> /// 负责处理倒序逻辑 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> int Comp(int x, int y) { return y - x; } int Compstring(string x, string y) { return y.Length - x.Length; }
6)获取数组最大值
public delegate bool DmyComp(object x, object y); private void button5_Click(object sender, EventArgs e) { #region 3.0.1 获取数组最大值(整数) //object[] intArr = { 1, 0, 3, 2, 4 }; //object maxobj = GetMax(intArr, intComp); //MessageBox.Show(maxobj.ToString()); #endregion #region 3.0.2获取pig对象数组的年龄最大的pig对象 object[] arrPig = { new Pig(){ Name="八戒", Age=500}, new Pig(){ Name="小猪", Age=1}, new Pig(){ Name="野猪", Age=4} }; object pig = GetMax(arrPig, PigComaByAge); Pig maxPig = pig as Pig; MessageBox.Show("Name" + maxPig.Name + " age=" + maxPig.Age); #endregion } bool PigComaByAge(object p1, object p2) { Pig pig1 = p1 as Pig; Pig pig2 = p2 as Pig; return pig1.Age - pig2.Age > 0; } /// <summary> /// 负责比较两个整数的大小 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> bool intComp(object x, object y) { return (int)x - (int)y > 0; } object GetMax(object[] arr, DmyComp comp) { //1.0 假设arr数组0下标的值就是最大 object max = arr[0]; //2.0 比较当前数组中的所有数据是否要大于max,如果大于则替换max的值 for (int i = 1; i < arr.Length; i++) { //判断如果大于则替换max的值 if (comp(arr[i], max)) { max = arr[i]; } } return max; }
7)利用事件向委托注册方法,并调用
/// <summary> /// 负责定义事件 /// </summary> public class DelegateHelper { public static event DmyFirstHander OnFirstHander; // public static event DmySecHander OnSecHander; /// <summary> /// 负责触发事件方法 /// </summary> public static void Run() { if (OnFirstHander != null) { //执行事件 OnFirstHander(); //本质: OnFirstHander.Invoke(); } }
/* 利用事件的优点: * 1、对委托进行了封装,只允许程序员进行 +=,和 -=操作,不允许进行直接赋值 * 2、一般是定义在类中,语法:public event DmyFirstHander myFirstHander; 3、利用事件操作委托,底层 1、拆成了一个私有的静态的委托变量 2、通过add_xx() ,remove_xxx()向私有的静态的委托变量 加方法和移除方法 */ private void button6_Click(object sender, EventArgs e) { //注册一个sayHelloCH //事件的+=本质:add_OnFirstHander() DelegateHelper.OnFirstHander += SayHelloCH; //报错:事件只能出现在+=,-=的左边,而此处出现在了=的左边 //DelegateHelper.OnFirstHander = null; DelegateHelper.OnFirstHander += Form1.SayHelloEN; //事件的+=本质:remove_OnFirstHander() DelegateHelper.OnFirstHander -= SayHelloCH; //触发事件 DelegateHelper.Run(); }