度量快速开发平台-专业、快速的软件定制快开平台

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 部件 流程 SQL
查看: 1651|回复: 5
打印 上一主题 下一主题

[分享] C#逆变

[复制链接]

182

主题

2120

帖子

4842

积分

论坛元老

Rank: 8Rank: 8

积分
4842
跳转到指定楼层
楼主
发表于 2020-4-6 20:50:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  在好多的.net的书籍中都看到过逆变和协变的概念,也在网上搜了一些关于这两个概念的解释,但是一直感觉似懂非懂的,直到最近在项目中实际遇到了一个问题,恰好用到了逆变,总算对逆变的理解又进了一步。
      逆变只能用到泛型接口和委托中,以前一直不理解为什么要用在泛型中,今天终于想明白了。在介绍逆变之前,先来说说泛型,泛型的作用就是算法的重用,举个例子
public class EntityBase<T>
    {
       DbContext db = new DbContext();
       public void Add(T Entity)
       {
           db.DbSet<T>.Add(Entity);
       }
       public void Remove(T Entity)
       {
           db.DbSet<T>.Remove(Entity);
       }
    }
看着很熟悉吧,对头,这就是我们在EF中常用的代码,每个实体类(映射到数据中的表的类)都用这个泛型类来定义,只需要指定T的类型就可以了,如果没有使用这个泛型类,那么我们不得不为每个实体类都定义一遍这些方法,所有类中的方法的代码除了类型,其他都一模一样。所以泛型就是算法的重用,泛型只对编译器可见,.net运行时环境是不知道泛型的,因为在编译时编译器自动根据T的类型,在每个类型中都生成一次方法的代码。
     泛型接口的逆变其实也是为了实现算法的重用,如下面的例子
public interface ICry<out T>
    {
        void Cry();
    }
    public class Animal
    {
        
    }
    public class Cat : Animal, ICry<Cat>
    {
        public void Cry()
        {
            Console.WriteLine("喵喵喵");
        }
    }
    public class Tiger : Animal, ICry<Tiger>
    {
        public void Cry()
        {
            Console.WriteLine("嗷嗷嗷");
        }
    }
    public class Nibian
    {
        public void Metho1(ICry<Animal> an)
        {
            an.Cry();
        }
    }
注意Nibian这个类Metho1方法,参数为ICry<Animal>,我们却可以传ICry<Cat>或ICry<Tiger>,就是因为我们在泛型接口中写了out这个逆变额关键字,虽然ICry<Cat>和ICry<Tiger>并不是同一个类,而且它俩和ICry<Animal>也不是父子类关系,按照OO原则,参数为父类,那么只能传父类和子类实例,如果没有逆变这个特性,我们还必须为每一个子类写一个这样方法,只是参数为ICry<Cat>和ICry<Tiger>,哈哈,看出来了把,逆变就是为了实现算法重用。最后是主程序Main方法
static void Main(string[] args)
        {
            ICry<Cat> c = new Cat();
            ICry<Tiger> t = new Tiger();
            Nibian nb = new Nibian();
            nb.Metho1(c);
            nb.Metho1(t);

        }

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

235

主题

2547

帖子

5835

积分

论坛元老

Rank: 8Rank: 8

积分
5835
沙发
发表于 2020-4-9 11:25:04 | 只看该作者
回复

使用道具 举报

542

主题

5916

帖子

1万

积分

作者

Rank: 7Rank: 7Rank: 7

积分
13589
板凳
发表于 2020-4-9 17:51:38 | 只看该作者
回复 支持 反对

使用道具 举报

182

主题

2120

帖子

4842

积分

论坛元老

Rank: 8Rank: 8

积分
4842
地板
 楼主| 发表于 2020-4-9 21:22:35 | 只看该作者
回复 支持 反对

使用道具 举报

542

主题

5916

帖子

1万

积分

作者

Rank: 7Rank: 7Rank: 7

积分
13589
5#
发表于 2020-4-10 17:36:57 | 只看该作者
回复 支持 反对

使用道具 举报

141

主题

1551

帖子

3573

积分

论坛元老

Rank: 8Rank: 8

积分
3573
6#
发表于 2020-4-10 18:02:11 | 只看该作者
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|重庆度量科技  本站关键词:快速开发平台

GMT+8, 2024-11-15 12:36 , Processed in 0.183818 second(s), 25 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表