以前对委托很熟呐!但,用进废退,好久不用,就不清楚了!!!今天在看一本书,就把这个委托重新拾起来吧!哈哈。
使用委托时,必须满足的4个条件
- 声明委托类型
delegate void StringMethod(string str)
delegate
关键字用来声明委托类型,其中void说明使用这个委托的方法的返回值必须是void,而小括号里的string参数说明,使用这个委托的方法必须要有一个字符串类型的参数才行。 必须有一个方法包含了要执行的代码
void PrintString(string x) OK void PrintInteger(int y) NO void PrintTwoString(string x,string y) NO int PrintString(string x) NO void PrintObject(object obj ) OK
必须创建一个委托实例
StringMethod smOne, smTwo; smOne = new StringMethod(Program.PrintString); smTwo = new StringMethod(Program.PrintObject);
必须调用(Invoke)委托实例
smOne.Invoke("Are You OK ?"); smTwo.Invoke("123");
我上面代码中创建委托时所使用的两个方法
public static void PrintString(string userInput) { Console.WriteLine(userInput); } public static void PrintObject(object obj) { Console.WriteLine(obj); }
如果你足够细心的话,你会发现一个问题!为什么上面参数类型是object的方法
PrintObject(object obj)
竟然也能使用参数类型为string的委托,这是为什么?因为C#中一切类型的基类都是object啊!!!object就是C#中一切类型的祖宗呐!只要object出马,哪个不让三分?哪个类型敢对祖宗不敬呢?其实是可以这么理解的,哈哈。
如果你也有打破沙锅问到底的精神,一定要搞清楚这个是为啥的话,也很简单,简单到只要一句话就能说清楚。
这个问题用官方的说法就是协变和逆变了,是不是感觉好懵?我也是哦!但是我研究了一下之后,发现,这所谓的协变和逆变的本质是一样的。有句话叫万变不离其宗,咱们只要抓住了它的本质,任它千般变化,我们自有火眼金睛,对不?
它们的本质就是跟谁玩的问题!就这么简单。举个例子,就像上面的那个问题,因为string的基类是object,也就是说,object是string的老大,所以string类型的参数见到老大了,还不得上去打个招呼,问个“老大好”啊!
上面说的是参数类型的老大问题,另外一个就是返回值的老大问题了。同样是老大说了算,委托定义的返回值类型的资历越大,那方法中的返回值类型如果是这个老大的小弟,就可以放行,毕竟是老大守门嘛!但是,有一点我们要记得就是,这个返回值类型是不认老大的,只认小弟!而参数是认老大,不认小弟!
总结一下所谓的协变(指的是返回值类型),逆变(参数类型)就是,返回值类型不认老大,只跟自己的小弟玩,参数类型是只跟老大玩,它们是不是在走极端呐!但是它们还有一个共性就是,都和自己一样级别的人玩。
委托的返回值很接地气,不拍马屁,只跟自己的下属玩;委托的参数很高冷,不跟小弟玩, 只跟自己的上司玩。另外还有一点就是,它们都和自己级别一样的人玩。这就是协变逆变啦!