您的位置:首页 > 编程语言 > C#

C#委托及其有趣的协变、逆变

2017-05-24 08:36 267 查看
以前对委托很熟呐!但,用进废退,好久不用,就不清楚了!!!今天在看一本书,就把这个委托重新拾起来吧!哈哈。

使用委托时,必须满足的4个条件

声明委托类型
delegate void StringMethod(string  str)
delegate
关键字用来声明委托类型,其中void说明使用这个委托的方法的返回值必须是void,而小括号里的string参数说明,使用这个委托的方法必须要有一个字符串类型的参数才行。
必须有一个方法包含了要执行的代码
void PrintString(string x)              OK
void PrintInteger(int y)                NO
void PrintTwoString(string x,st
4000
ring 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类型的参数见到老大了,还不得上去打个招呼,问个“老大好”啊!上面说的是参数类型的老大问题,另外一个就是返回值的老大问题了。同样是老大说了算,委托定义的返回值类型的资历越大,那方法中的返回值类型如果是这个老大的小弟,就可以放行,毕竟是老大守门嘛!但是,有一点我们要记得就是,这个返回值类型是不认老大的,只认小弟!而参数是认老大,不认小弟!总结一下所谓的协变(指的是返回值类型),逆变(参数类型)就是,返回值类型不认老大,只跟自己的小弟玩,参数类型是只跟老大玩,它们是不是在走极端呐!但是它们还有一个共性就是,都和自己一样级别的人玩。

委托的返回值很接地气,不拍马屁,只跟自己的下属玩;委托的参数很高冷,不跟小弟玩, 只跟自己的上司玩。另外还有一点就是,它们都和自己级别一样的人玩。这就是协变逆变啦!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: