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

  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. V$INSTANCE 字段说明

    http://blog.csdn.net/wyzxg/article/details/4728622 http://blog.csdn.net/warden2010/article/details/6 ...

  2. HDU 4344

    其实不过是大整数分解... 注意两点:注意L 不能==N 但是,N却可以是素数...囧 #include <iostream> #include <cstdio> #inclu ...

  3. 求最长回文子串,O(n)复杂度

    最长回文子串问题-Manacher算法 最长回文串问题是一个经典的算法题. 0. 问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 假设一个字符串正着读和反着读是一样的,那它就是回 ...

  4. Android scrollTo() scrollBy() Scroller解说及应用

    版本号:1.0  日期:2014.6.17  2014.6.18 版权:© 2014 kince 转载注明出处   scrollTo() .scrollBy()及 Scroller在视图滑动中常常使用 ...

  5. xhprof安装&amp;&amp;使用

    听同事说起过一个php性能分析扩展,叫xhprof,近期了解了下. XHProf 是一个轻量级的分层性能測量分析器. 在数据收集阶段.它跟踪调用次数与測量数据,展示程序动态调用的弧线图. 它在报告.后 ...

  6. Oracle学习(二):过滤和排序

    1.知识点:能够对比以下的录屏进行阅读 SQL> --字符串大写和小写敏感 SQL> --查询名叫KING的员工信息 SQL> select * 2 from emp 3 where ...

  7. String与StringBuffer的差别

    String 是一个常量,即一旦创建不可更改 输出结果为:helloworldjeok 看似.string变量name的值改变了,事实上此name非彼name. 输出结果为: sex:hello wo ...

  8. 深入理解Oracle索引(1):INDEX SKIP SCAN 和 INDEX RANGE SCAN

    ㈠ Index SKIP SCAN                当表有一个复合索引,而在查询中有除了索引中第一列的其他列作为条件,并且优化器模式为CBO,这时候查询计划就有可能使用到SS       ...

  9. 2017-3-6 leetcode 118 169 189

    今天什么都没发生 ================================================= leetcode118 https://leetcode.com/problems ...

  10. vue中通过js控制页面样式方法

    在使用vue.js框架的时候,有时候会希望在页面渲染完成之后,再执行函数方法来处理初始化相关的操作,如果只处理页面位置.宽或者高时,必须要在页面完全渲染之后才可以,页面没有加载完成之前,获取到的宽高不 ...