首先看一段测试代码,自己写的

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. man OneMan = new man();
  6. var d = OneMan.CreatNewObject() as man ; // 这里是父类object转换为子类man,逆变
  7. Console.WriteLine("这是OneMan的类 "+OneMan); // 打印对象,默认打印对象的toString方法
  8. d.Speak();
  9. Console.ReadKey();
  10. }
  11. }
  12. public class man
  13. {
  14. public object CreatNewObject() // 这里是子类变为object父类,是协变
  15. {
  16. son g = new son();
  17. return g;
  18. }
  19. public override string ToString() // 覆写ToString方法后
  20. {
  21. string result = "I的值为{0},A为";
  22. return result;
  23. }
  24. public void Speak()
  25. {
  26. Console.WriteLine("this is a too much top!");
  27. }
  28. }
  29. public class son: man
  30. {
  31. }

测试结果
1.逆变和协变的条件是两者存在继承关系(或者说两者间有直线),两个不同的类是无法逆变或者协变的
2.直接打印类默认调用的是类的ToString方法,如果类没有重写ToString方法,默认调用的就是object的ToString方法

in 参数      : 表示参数可能会逆变
out 参数    : 表示参数可能会协变

一个比较好的实例
  1. // 第一种通过as转换类型来调用类中的方法
  2. var a1 = GetAnimal() as Animal;
  3. a1.Speak();
  4. // 第二种是通过反射将object中的方法调出来
  5. a1.GetType().GetMethod("Speak").Invoke(a1, null);
  6. // 第三种调用方法是通过dynamic关键字,在运行时将object转换为Animal类,直接调用类中的方法
  7. dynamic a2 = GetAnimal();
  8. a2.Speak(); // 注意,这个dynamic是没有智能提示的,要把字母全部输出正确才行
  9. Type aa = Assembly.Load("dogs").GetType("dogs.Class1"); // dogs是namespace名称,Class1是类名,GetType方法可以直接从命名空间下的类名取得该类的Type类型/属性
  10. dynamic bb = Activator.CreateInstance(aa);
  11. bb.Voice(); // Voice()是类中的方法
  12. a1.age.a = "jingya";
  13. a1.age.b = 23;
  14. Console.WriteLine(a1.age.a);
  15. Console.ReadKey();
  16. }
  17. static object GetAnimal() // c#中的很多返回值都是object,通过反射才能调用其中的方法,反射太麻烦了,不如用dynamic简单,也没有dynamic性能高
  18. {
  19. return new Animal() { name = "xiaolizi Animal " };
  20. }
  21. }
  22. public class Animal
  23. {
  24. public dynamic age { get; set; }
  25. public string name = "a ben mao ";
  26. public void Speak()
  27. {
  28. Console.WriteLine("this is a Animal Speak voice");
  29. }









C#-逆变 协变 反射 代码的更多相关文章

  1. 【温故而知新-万花筒】C# 异步编程 逆变 协变 委托 事件 事件参数 迭代 线程、多线程、线程池、后台线程

    额基本脱离了2.0 3.5的时代了.在.net 4.0+ 时代.一切都是辣么简单! 参考文档: http://www.cnblogs.com/linzheng/archive/2012/04/11/2 ...

  2. .NET中的逆变协变

    MSDN上的说法: 协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型----------(注 ...

  3. [改善Java代码]警惕泛型是不能协变和逆变的

    什么叫做协变(covariance)和逆变(contravariance)? 在变成语言的类型框架中,协变和逆变是指宽类型和窄类型在某种情况下(如参数,泛型,返回值)替换或交换的特性,简单的说,协变是 ...

  4. C# 泛型的协变和逆变

    1. 可变性的类型:协变性和逆变性 可变性是以一种类型安全的方式,将一个对象当做另一个对象来使用.如果不能将一个类型替换为另一个类型,那么这个类型就称之为:不变量.协变和逆变是两个相互对立的概念: 如 ...

  5. 泛型类型的协变(covariant)和逆变

    官网:http://msdn.microsoft.com/zh-cn/library/dd799517.aspx 原文链接:http://book.51cto.com/art/201112/30857 ...

  6. .NET 4.0中的泛型的协变和逆变

    转自:http://www.cnblogs.com/jingzhongliumei/archive/2012/07/02/2573149.html 先做点准备工作,定义两个类:Animal类和其子类D ...

  7. 转载.NET 4.0中的泛型的协变和逆变

    先做点准备工作,定义两个类:Animal类和其子类Dog类,一个泛型接口IMyInterface<T>, 他们的定义如下:   public class Animal { } public ...

  8. C# 逆变与协变

    该文章中使用了较多的 委托delegate和Lambda表达式,如果你并不熟悉这些,请查看我的文章<委托与匿名委托>.<匿名委托与Lambda表达式>以便帮你建立完整的知识体系 ...

  9. 解读经典《C#高级编程》最全泛型协变逆变解读 页127-131.章4

    前言 本篇继续讲解泛型.上一篇讲解了泛型类的定义细节.本篇继续讲解泛型接口. 泛型接口 使用泛型可定义接口,即在接口中定义的方法可以带泛型参数.然后由继承接口的类实现泛型方法.用法和继承泛型类基本没有 ...

随机推荐

  1. 洛谷 1144 最短路计数 bfs

    洛谷1144 最短路计数 传送门 其实这道题目的正解应该是spfa里面加一些处理,,然而,,然而,,既然它是无权图,,那么就直接bfs了,用一个cnt记录一下每一个点的方案数,分几种情况讨论一下转移, ...

  2. Google NewSQL之Spanner

    谷歌分布式三宝 BigTable.GFS.MapReduce这传说中的谷歌分布式三驾马车,虽然谷歌没有公开具体实现代码,但却公布了相应论文,对分布式文件系统.大数据挖掘和NoSQL流行起了重大促进作用 ...

  3. 转-----------------------js window.open() 操作

    <% if request("infoid")<>"" then set rs=conn.execute("select * fro ...

  4. test environment bug

    pxj::EsgServiceImpl.kmsProcess->Get:ESG JAR return data is:{"code":10000,"data&quo ...

  5. Api接口服务的设计和安全解决方案

    这个涉及到两个方面问题:一个是接口访问认证问题,主要解决谁可以使用接口(用户登录验证.来路验证)一个是数据数据传输安全,主要解决接口数据被监听(HTTPS安全传输.敏感内容加密.数字签名) 普通网站应 ...

  6. c/s winform打包和部署

    1:vs2010新建  安装项目  左边出现3个文件夹 2:点击 第一个文件夹-> “应用程序文件夹”    将 bin 目录下的所以文件  拖进 右边的空白处:c:\windows\syste ...

  7. jar文件配置冲突问题transformResourcesWithMergeJavaResForDebug

    先看本人AS报错异常 Error:Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'. > c ...

  8. android webview一些注意事项(持续更新)

    1.loadUrl() 的参数必须“http://”开头: 2.如果用到内部类获取页面内容,此类不能混淆: 3.2中情况保持不混淆需要将webview所在的包都保持不混淆,常规的保持类不混淆不生效: ...

  9. mysql中间件研究(tddl atlas cobar sharding-jdbc)

    mysql-proxy是官方提供的mysql中间件产品可以实现负载平衡,读写分离,failover等,但其不支持大数据量的分库分表且性能较差.下面介绍几款能代替其的mysql开源中间件产品,Atlas ...

  10. vue 中判断向上滚动还是向下滚动

    <script> export default { data(){ return{ i = 0 } }, mounted () { window.addEventListener('scr ...