c# 协变和逆变
类别:编程学习 浏览量:364
时间:2014-9-26 c# 协变和逆变
c# 协变和逆变
由子类向父类方向转变是协变,用out关键字标识,由父类向子类方向转变是逆变,用in关键字
协变和逆变的应用
一、 数组的协变
Animal[] animalArray =
new
Dog[]{};
说明:声明的数组数据类型是Animal,而实际上赋值时给的是Dog数组;每一个Dog对象都可以安全的转变为Animal。Dog向Animal方法转变是沿着继承链向上转变的所以是协变
二. 委托中的协变和逆变
1、委托中的协变
C# 代码 复制
//委托定义的返回值是Animal类型是父类
public delegate Animal GetAnimal();
//委托方法实现中的返回值是Dog,是子类
static Dog GetDog(){return new Dog();}
//GetDog的返回值是Dog, Dog是Animal的子类;返回一个Dog肯定就相当于返回了一个Animal;所以下面对委托的赋值是有效的
GetAnimal getMethod = GetDog;
2、委托中的逆变
//委托中的定义参数类型是Dog
public delegate void FeedDog(Dog target);
//实际方法中的参数类型是Animal
static void FeedAnimal(Animal target){}
// FeedAnimal是FeedDog委托的有效方法,因为委托接受的参数类型是Dog;而FeedAnimal接受的参数是animal,Dog是可以隐式转变成Animal的,所以委托可以安全的的做类型转换,正确的执行委托方法;
FeedDog feedDogMethod = FeedAnimal;
//定义委托时的参数是子类,实际上委托方法的参数是更宽泛的父类Animal,是父类向子类方向转变,是逆变
三. 泛型委托的协变和逆变
1、 泛型委托中的逆变
//委托声明:
public delegate void Feed<in T>(T target);
//Feed委托接受一个泛型类型T,注意在泛型的尖括号中有一个in关键字,这个关键字的作用是告诉编译器在对委托赋值时类型T可能要做逆变
//先声明一个T为Animal的委托
Feed<Animal> feedAnimalMethod = a=>Console.WriteLine(“Feed animal lambda”);
//将T为Animal的委托赋值给T为Dog的委托变量,这是合法的,因为在定义泛型委托时有in关键字,如果把in关键字去掉,编译器会认为不合法
Feed<Dog> feedDogMethod = feedAnimalMethod;
2、泛型委托中的协变
//委托声明
public delegate T Find<out T>();
//Find委托要返回一个泛型类型T的实例,在泛型的尖括号中有一个out关键字,该关键字表明T类型是可能要做协变的
//声明Find<Dog>委托
Find<Dog> findDog = ()=>new Dog();
//声明Find<Animal>委托,并将findDog赋值给findAnimal是合法的,类型T从Dog向Animal转变是协变
Find<Animal> findAnimal = findDog;
四. 泛型接口中的协变和逆变
1、泛型接口中的逆变
//接口定义:
public interface IFeedable<in T>
{
void Feed(T t);
}
//接口的泛型T之前有一个in关键字,来表明这个泛型接口可能要做逆变
//如下泛型类型FeedImp<T>,实现上面的泛型接口;需要注意的是协变和逆变关键字in
public class FeedImp<T>:IFeedable<T>
{
public void Feed(T t){
Console.WriteLine(“Feed Animal”);
}
}
//使用接口逆变:
IFeedable<Dog> feedDog = new FeedImp<Animal>();
//上面的代码将FeedImp<Animal>类型赋值给了IFeedable<Dog>的变量;Animal向Dog转变了,所以是逆变
2、泛型接口中的协变
//接口的定义:
public interface IFinder<out T>
{
T Find();
}
//泛型接口的泛型T之前用了out关键字来说明此接口是可能要做协变的;如下泛型接口实现类
public class Finder<T>:IFinder<T> where T:new()
{
public T Find(){
return new T();
}
}
//使用协变,IFinder的泛型类型是Animal,但是由于有out关键字,我可以将Finder<Dog>赋值给它
IFinder<Animal> finder = new Finder<Dog>();
标签:接口
您可能感兴趣
- laravel开发登录接口(解决laravel5中auth用户登录其他页面获取不到登录信息的问题)
- web接口测试中需要测试的几个点
- python 调钉钉接口(python3实现钉钉消息推送的方法示例)
- php商城支付接口(php实现银联商务公众号+服务窗支付的示例代码)
- 使用Fiddler测试WebApi接口
- 阿里云网站cdn加速(阿里云CDN刷新链接接口实践)
- nodejs如何识别接口(Node实现搜索框进行模糊查询)
- 支付宝接口中notify_url 与 return_url 的区别
- tp5微信支付接口开发案例(PHP实现的微信APP支付功能示例基于TP5框架)
- html5 web技术(html5视频常用API接口的实战示例)
- api接口安全方面的几个建议
- axios调用接口(如何实现axios的自定义适配器adapter)
- thinkphp5开发教程(thinkPHP5框架接口写法简单示例)
- pythonflask编写接口(Python Flask框架模板操作实例分析)
- python人脸识别库有几个(Python人脸识别第三方库face_recognition接口说明文档)
- vue 访问后台接口(vue轮询请求解决方案的完整实例)
- 自制橡皮泥(自制橡皮泥)
- 还在卖 禁药西布曲明网上论斤卖(还在卖禁药西布曲明网上论斤卖)
- 微商在朋友圈热卖的 DL减肥咖啡 含违禁药物,你还敢买吗(微商在朋友圈热卖的)
- 八一节,说说中国女兵(八一节说说中国女兵)
- 王治郅菜鸟赛季已让八一带入正轨,大郅七大经典语录或是成功秘诀(王治郅菜鸟赛季已让八一带入正轨)
- 庆八一,重读经典红色语录,感悟互联网发展硬道理(重读经典红色语录)
热门推荐
- iis运行php程序(Windows2003+IIS7 Express使用FastCgi运行php)
- python真的能高效处理excel报表吗(Python数据报表之Excel操作模块用法分析)
- 工作如何分轻重缓急
- dedecms栏目怎么设置(织梦DedeCms实现调用单页文章内容的方法)
- dedecms安装使用教程(网站子目录安装dedecms导致网页布局混乱的解决方法)
- 微信小程序静态页面详情(微信小程序基础教程之echart的使用)
- laravel怎么查询信息过滤(laravel多条件查询方法and,or嵌套查询)
- 前端表单验证(AmazeUI的JS表单验证框架实战示例分享)
- canvas怎么压缩图片(使用canvas压缩图片大小的方法示例)
- 织梦dedecms开启付费授权(织梦dedeCMS二次开发文档手册 程序目录详解以及数据表结构字段)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9