老郑的博客

木叶飞舞之处,火亦生生不息!

c# 协变和逆变

C#可变性类型

  可变性只支持引用类型,禁止用户定义的转换。

  • 协变性

  如果某个返回的类型可以由其子类替换,那么这个类型就是支持协变的

  • 逆变性

   如果某个参数类型可以由其父类替换,那么这个类型就是支持逆变的

可变性参数

  只有接口和委托可以拥有可变的类型参数

  • in

    参数是逆变
  • out

    参数是协变

实例

public class A
{}
public class B:A

协变

子类变成父类

A b=new B();//协变可正常转换

逆变

父类变成子类

B b=new A();//这样会直接报错
B b=(B)(new A());//强制转换

泛型的协变和逆变

逆变

  实例化参数是子类,泛型接口当中是父类,如果想要正常创建对象,需要在泛型参数上加上in标记

定义泛型接口

public interface IUserService<in T>
{
        
}

定义业务层实现接口

 public class UserService: IUserService<A>
{
}

实例化

     static void Main(string[] args)
    {
     IUserService<B> s =new  UserService();
    }

如果不加in的话,会报错

无法将类型“ConsoleApp6.IServer.UserService”
隐式转换为“ConsoleApp6.IServer.IUserService<B>”。
存在一个显式转换(是否缺少强制转换?)

协变

  实例化参数是子类,泛型接口当中是父类,如果想要正常创建对象,需要在泛型参数上加上in标记

定义泛型接口

public interface IUserService<in T>
{
        
}

定义业务层实现接口

 public class UserService: IUserService<B>
{
}

实例化

     static void Main(string[] args)
    {
     IUserService<A> s =new  UserService();
    }

如果不加in的话,会报错

无法将类型“ConsoleApp6.IServer.UserService”
隐式转换为“ConsoleApp6.IServer.IUserService<A>”。
存在一个显式转换(是否缺少强制转换?)
posted @ 2019-10-29 18:35  zyz1  阅读(174)  评论(0编辑  收藏  举报