.Net逆变与协变

  总结:

  1. 协变与逆变只针对引用类型
  2. 协变:把子类型 赋值给 父类型,string 赋值给object叫‘类型兼容’,string[]赋值给object[] 叫协变
  3. 逆变:把父类型 赋值给 子类型,且不需要强制转换进行赋值,已经帮我们进行了隐式转换

1、接口中

  • 协变式(泛型前加 out),只能用于方法的返回值
  • 逆变式(泛型前加   in),只能用于方法的参数签名

首先来看一下接口的例子:

 1     /// <summary>
 2     /// 接口
 3     /// </summary>
 4     /// <typeparam name="Tin">Tin为逆变式,只能用于接口中函数的参数签名</typeparam>
 5     /// <typeparam name="Tout">Tout为协变式,只能用于接口中函数的返回值类型</typeparam>
 6     public interface Face<in Tin, out Tout>
 7     {
 8         //Tin Fun(double instance);错误的函数定义,编译就会报错
 9         double Fun(Tin instance);
10 
11         Tout Fun(double instance);
12         //double Fun(Tout instance);错误的函数定义,编译就会报错
13     }

 

 

2、在委托中:

  • 不能将函数参数定义成协变,也不能将返回类型定义成逆变
1    /// <summary>
2     /// 委托
3     /// </summary>
4     /// <typeparam name="Tin">Tin为逆变式,只能用于委托中函数的参数签名</typeparam>
5     /// <typeparam name="Tout">Tout为协变式,只能用于委托中函数的返回值类型</typeparam>
6     /// <param name="instance"></param>
7     /// <returns></returns>
8     public delegate Tout MyDel<in Tin, out Tout>(Tin instance);
9     //public delegate Tin MyDel1<in Tin, out Tout>(Tout instance);错误的委托定义 

 下面来看看Action委托

 1 class Program
 2 {
 3     static void Main(string[] args)
 4     {
 5         //以下能将Action<object>的实例赋值给Action<string>实例的原因就是由于Action委托是一个逆变式
 6         Action<object> acObj = ActionFuncObj;
 7         Action<string> acStr = acObj;
8 //以下表达式是错误的,因为Action是一个逆变式,所以无法将Action<string>实例赋值给Action<object>实例 9 //Action<string> acStr2 = ActionFuncStr; 10 //Action<object> acObj2 = acStr2; 11 } 12 static void ActionFuncStr(string str) 13 { 14 Console.WriteLine(str); 15 } 16 static void ActionFuncObj(object obj) 17 { 18 Console.WriteLine(obj); 19 } 20 }

 

 下面来看看Func委托

 1 class Program
 2 {
 3     static void Main(string[] args)
 4     {
 5         //以下能将Func<string, object>的实例赋值给Func<string, object>实例的原因就是由于Func委托是一个协变式
 6         Func<string, string> funcStr = FuncStr;
 7         Func<string, object> funcObj = funcStr;
 8 
 9         //以下表达式是错误的,因为Func是一个协变式,所以无法将Func<string, object>实例赋值给Func<string, string>实例
10         //Func<string, string> funcStr2 = funcObj;
11     }
12     static string FuncStr(string str)
13     {
14         return str;
15     }
16 }

 

posted @ 2014-09-11 12:16  VitoWu  阅读(106)  评论(0)    收藏  举报