知乎大佬多系列
作者:Junased
链接:https://www.zhihu.com/question/28932542/answer/42769044
来源:知乎
感觉官方说法可以搜索到,我就说理解。
先说结论(我的理解):声明一个事件,类似于声明一个进行封装了的委托。
详细的:
- 委托
这个可以简单的理解为: 把方法当成方法的参数
看起来有点绕口,咱们先写个“你好,世界!”
public void HelloWorld(string name) { ByEnglish(name); } public void ByEnglish(string name) { Console.WriteLine("Hello World By" + name); }
好了,现在产品经理打算整个中文版的,好,咱改!
public void ByChinese(string name) { Console.WriteLine("你好,世界!作者:" + name); }
public enum Language { English,CHinese } public void HelloWorld(string name,Language lan) { switch(lan) { case Language.English:ByEnglish(string name);break; case Language.Chinese:ByChinese(string name);break; } }
差不多这样的话可以满足目前的需求了
现在突然又蹦出来个意大利人想弄出个意大利版(我不会意大利语,不贴了),按照上面的思路,大概也能整出来。
然后,产品经理说:这个方法咱要全球化,每个语言都要照顾到。(NMB)按照上面的思路来,我觉得可以抽刀砍人了。
但是法律这玩意儿可怕哟,想到这个我的心儿就碎了。所以咱们还是把“委托”掏出来吧!
委托上面的说的是:把方法当做方法的参数,大概就是这个样子
public void HelloWorld(string name, 方法 方法名)
1 private static delegate void HelloWorldDelete(string name) 2 public void HelloWorld(string name, HelloWorldDelete chooseLanguage) 3 { 4 chooseLanguage(name); 5 } 6 private static void ByEnglish(string name) 7 { 8 Console.WriteLine("Hello World By" + name); 9 } 10 private static void ByChinese(string name) 11 { 12 Console.WriteLine("你好,世界!作者:" + name); 13 } 14 static void Main(string[] args) 15 { 16 HelloWorld("张三",ByChinese); 17 HelloWorld("ZhangThree",ByEnglish); 18 }
输出:
你好,世界!作者:张三
Hello World By ZhangThree
static void Main(string[] args) { HelloWorldDelete delegateEnglish,delegateChinese; delegateEnglish = ByEnglish; delegateChinese = ByChinese; HelloWorld("张三",delegateChinese); HelloWorld("ZhangThree",delegateEnglish); }
输出不变。
换个姿势绑定(只写Main中的,因为其他的没变):static void Main(string[] args) { HelloWorldDelete delegateEnglish,delegateChinese; delegateEnglish = ByEnglish; delegateChinese = ByChinese; HelloWorld("张三",delegateChinese); HelloWorld("ZhangThree",delegateEnglish); }
输出:
Hello World By 张三
你好,世界!作者:张三
static void Main(string[] args) { HelloWorldDelete delegateAll; delegateAll = ByEnglish; //“=”表示赋值 delegateAll += ByChinese; //“+=”表示绑定,委托不能直接+=,会出现“未赋值 //什么的错误”;相应的“-=”表示解除绑定 delegateAll ("张三"); }
- 事件
写代码讲究个“说学逗唱”,说错了,讲究个“面向对象”。
面向对象:封装、继承、多态。
封装
把上面的封装一下
public delegate void HelloWorldDelegate(string name); public class HelloWorldClass { HelloWorldDelegate del; public void HelloWorld(string name) { if(del != null) //有方法注册了 del(name); //委托调用所有注册的方法 } } class Program { private static void ByEnglish(string name) { Console.WriteLine("Hello World By" + name); } private static void ByChinese(string name) { Console.WriteLine("你好,世界!作者:" + name); } static void Main(string[] args) { HelloWorldClass hw = new HelloWorldClass(); hw.del = ByEnglish; hw.del += ByChinese; hw.HelloWorld("张三"); } }
输出:
Hello World By 张三
你好,世界!作者:张三
public class Number { private int num; public int Num { get { return; } set { num = value; } } }
所以,把“事件”掏出来:
事件:事件至于委托,类似于属性至于字段。不管声明成public还是protected,都是private的。
public delegate void HelloWorldDelegate(string name); public class HelloWorldClass { public event HelloWorldDelegate del; public void HelloWorld(string name) { del(name); //委托调用所有注册的方法 } } class Program { private static void ByEnglish(string name) { Console.WriteLine("Hello World By" + name); } private static void ByChinese(string name) { Console.WriteLine("你好,世界!作者:" + name); } static void Main(string[] args) { HelloWorldClass hw = new HelloWorldClass(); hw.del = ByEnglish; //会出现编译错误 hw.del += ByChinese; //直接+=就好 hw.HelloWorld("张三"); } }
输出:
你好,世界!作者:张三