1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4.  
  5. namespace CovarientAndContraVarient
  6. {
  7. class Program
  8. {
  9. static object GetObject() { return null; }
  10. static void SetObject(object obj) { }
  11.  
  12. static string GetString() { return ""; }
  13. static void SetString(string str) { }
  14.  
  15. static void Main(string[] args)
  16. {
  17. Func<object> getString = GetString;
  18.  
  19. Action<string> setString = SetObject;
  20.  
  21. Func<string> getString1 = GetString;
  22.  
  23. //1. Delegate variable implicitly cast is not valid until .net 4.0
  24. Func<object> setString2 = getString1;
  25.  
  26. //Assignment compatibility,
  27. IEnumerable<String> test = new List<string>();
  28.  
  29. //covariance OUT == > Covariance
  30. IEnumerable<object> test1 = new List<string>();
  31.  
  32. //Assignment compatibility
  33. Action<Object> objAction = StaticMethod;
  34.  
  35. //ContraConvariance , IN === > ContraConvariance
  36. Action<String> stringAction = StaticMethod;
  37.  
  38. //2. Array Covariance, support in C# 1.0
  39. object[] objArray = new String[] { "a", "b", "c" };
  40.  
  41. //Covariance in array is not safe, below code will throw exception
  42. objArray[] = ;
  43.  
  44. //3. Co/contra- Variance don't support value type, below code is invalid
  45. //IEnumerable<object> objects = new List<int>();
  46.  
  47. //you can use an interface instance that has methods with more
  48. //derived return types than originally specified (covariance--OUT)
  49. //or that has methods with less derived parameter types (contravariance--IN).
  50.  
  51. //Contravariance
  52. IMyTest<FileStream> myTestInstance = new MyTestClass1<Stream>();
  53.  
  54. IMyTest<Stream> myTest = new MyTestClass1<Stream>();
  55.  
  56. //covariance
  57. IMyTest1<object> myTest1Instance = new MyTestClass2<string>();
  58.  
  59. IMyTest<FileStream> myTestInstance1 = myTest;
  60.  
  61. //Below Code, you will think it is a little strange, but absolutely it works well!!!!!!!!!
  62. //4. You can mark a generic type parameter as covariant if it is used only as a method return
  63. //type and is not used as a type of formal method parameters.
  64. //5. And vice versa, you can mark a type as contravariant if it is used only as a type of
  65. //formal method parameters and not used as a method return type.
  66. IMyFirstTestClass<object, string> testClass = null;
  67. IMyFirstTestClass<string, object> testClass1 = testClass;
  68. }
  69.  
  70. public static void StaticMethod(object o)
  71. {
  72. }
  73. }
  74.  
  75. public interface IMyFirstTestClass<in T1, out T2>
  76. {
  77. T2 DoSomething(T1 para);
  78. }
  79.  
  80. //6. Variant type only can declared in interfaces and delegates only!!!!!!!
  81. //public class MyTestClass<in T>
  82. //{
  83.  
  84. //}
  85.  
  86. //Contravariance
  87. public interface IMyTest<in T>
  88. {
  89. void PrintTest(T param);
  90. }
  91.  
  92. //7. Below code, T is invariance, if you want to it be Contravariance, you must declare it explicitly.
  93. //Same as covariance
  94. public interface IMyTestExtend<T> : IMyTest<T>
  95. {
  96. }
  97.  
  98. public class MyTestClass1<T> : IMyTest<T>
  99. {
  100. public void PrintTest(T para)
  101. {
  102. Console.WriteLine("This is " + typeof(T) + " PrintTest Method!");
  103. }
  104. }
  105.  
  106. //Covariance
  107. public interface IMyTest1<out T>
  108. {
  109. T PrintTest();
  110. }
  111.  
  112. public class MyTestClass2<T> : IMyTest1<T>
  113. {
  114. public T PrintTest()
  115. {
  116. Console.WriteLine("This is " + typeof(T) + " PrintTest Method!");
  117. return default(T);
  118. }
  119. }
  120.  
  121. public delegate void MyHander<in T>(T para);
  122.  
  123. //Below method declaration is invalid, because 'in' is contravariance, it only can be in paramter type
  124. //public delegate T MyHander1<in T>(T para);
  125.  
  126. public delegate T MyHandler2<out T>(object para);
  127.  
  128. //Below method declaration is invalid, because 'out' is covariance, it only can be in returned type
  129. //public delegate void MyHandler2<out T>(T para);
  130.  
  131. }

FYI: http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx

Covarience And ContraVariance的更多相关文章

  1. 不变性、协变性和逆变性(Invariance, Covariance & Contravariance)

    源码下载 一.里氏替换原则(Liskov Substitution Principle LSP) 我们要讲的不是协变性和逆变性(Covariance & Contravariance)吗?是的 ...

  2. Covariance and Contravariance in C#, Part One

    http://blogs.msdn.com/b/ericlippert/archive/2007/10/16/covariance-and-contravariance-in-c-part-one.a ...

  3. 协变(covariance),逆变(contravariance)与不变(invariance)

    协变,逆变与不变 能在使用父类型的场景中改用子类型的被称为协变. 能在使用子类型的场景中改用父类型的被称为逆变. 不能做到以上两点的被称为不变. 以上的场景通常包括数组,继承和泛型. 协变逆变与泛型( ...

  4. Covariance and Contravariance (C#)

    Covariance and Contravariance (C#) https://docs.microsoft.com/en-us/dotnet/articles/csharp/programmi ...

  5. C# 逆变(Contravariance)/协变(Covariance) - 个人的理解

    逆变(Contravariance)/协变(Covariance) 1. 基本概念 官方: 协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始 ...

  6. Covariance and Contravariance in C#, Part Two: Array Covariance

    http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-a ...

  7. C#中的协变(Covariance)和逆变(Contravariance)

    摘要 ● 协变和逆变的定义是什么?给我们带来了什么便利?如何应用? ● 对于可变的泛型接口,为什么要区分成协变的和逆变的两种?只要一种不是更方便吗? ● 为什么还有不可变的泛型接口,为什么有的泛型接口 ...

  8. 《徐徐道来话Java》(2):泛型和数组,以及Java是如何实现泛型的

    数组和泛型容器有什么区别 要区分数组和泛型容器的功能,这里先要理解三个概念:协变性(covariance).逆变性(contravariance)和无关性(invariant). 若类A是类B的子类, ...

  9. .NET中的逆变协变

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

随机推荐

  1. liux vim命令

    命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filename 打开vim ...

  2. 【转】有趣的Autolayout示例-Masonry实现

    原文网址:http://tutuge.me/2015/05/23/autolayout-example-with-masonry/ 好久没有写Blog了,这段时间有点忙啊=.=本文举了3个比较有“特点 ...

  3. Android Studio进行NDK编程

  4. [转] C#实现自动化Log日志

    qing2005原文地址 C#实现自动化Log日志 在开发项目的时候,我们不免要使用Log记录日志,使用最多的是Log4Net和EntLib Log,在需要记录日志的代码处加入log.Write(日志 ...

  5. slidingmenu + fragment 左右菜单滑动

                           content_frame.xml <?xml version="1.0" encoding="utf-8" ...

  6. 20、内存溢出(Out of Memory)

     内存引用(释放强引用) Object obj=new Object(); obj = null;  内存引用(使用软引用) 软引用是主要用于内存敏感的高速缓存.在jvm报告内存不足之前会清 除所 ...

  7. SQL 的一些概念问答

    1.触发器的作用? 答:触发器是一中特殊的存储过程,主要是通过事件来触发而被执行的.它可以强化约束,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化.可以联级运算.如, ...

  8. 【转】发布python的包至pypi服务器

    [原文链接]http://yejinxin.github.io/distribute-python-packages-to-pypi-server/ 使用pip或easy_install可以管理和安装 ...

  9. mapreduce优化总结

    集群的优化 1.合理分配map和reduce任务的数量(单个节点上map任务.reduce任务的最大数量) 2.其他配置 io.file.buffer.size hadoop访问文件的IO操作都需要通 ...

  10. JavaScript中的重载解读

    在JavaScript中有一种特殊的数据类型---Function类型,JavaScript的每个函数都是Function类型的实例.由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与 ...