写点什么

.NET 泛型中的协变与逆变

  • 2008-08-29
  • 本文字数:825 字

    阅读完需:约 3 分钟

当前.NET 语言如 VB 和 C#还不支持泛型的协变(covariance)与逆变(contravariance)。尽管微软中的很多人也在谈论它,但是在不远的将来这还是不太可能出现。对协变与逆变的完整介绍要花很长时间。基于此,请大家参考 Eric Lippert 的关于C#中的协变与逆变的系列文章。为了在VB 中增加协变与逆变的泛型支持,Lucian Wischik 提出了下面的语法。

类型参数可由关键字“In”和“Out”修饰。“In”类型只能作为方法参数。与此类似,“Out”类型只能作为方法的返回类型。

使用Out 类型的一个例子就是IEnumerable(Of T)。如果某函数接受一个IEnumerable(Of Animal) 类型参数,那么我们就可以给它传一个IEnumerable(of Bird)。对于In 类型,一个不太恰当的例子就是顺序。看一下下面的接口:

<pre id="np7-15">Interface IWriter(Of T)<br id="np7-16"></br> Write(value As T)如果你向接受 Writer(Of Animal) 类型参数的函数传一个 IWriter(Of Bird),当然就不对了。该方法可以将 Animal 的任何子类传给 IWriter.Write,但是它只接受 Birds。

如果使用注解,该接口看起来像下面这样:

<pre id="np7-19">Interface IEnumerable(Of Out T)<p>Interface IWriter(Of In T)</p>这是针对 VB 编写的,它也可以用在 C#上。

<pre id="np7-23">interface IEnumerable<out T><p>interface IWriter<in T> </p><br id="ku3p"></br>不幸的是,这种语法并不能直接应用在大多数常见的场景中。比如 IList(Of T),当传给一个向集合中写入的方法时,T 应该是 In 类型。但是当传给一个从集合中读取的方法时,T 应该是 Out 类型。或许这里应该针对 IList 创建一个基类,该类会将接受 T 与返回 T 的方法区分开来。

追溯过去,C#和 VB 都支持数组协变(out/IEnumerable 情况),尽管在逆变的情况下这会导致运行时错误(in/IWriter 情况)。这样做的目的是使 C#更兼容于 Java。大多数人都认为这是一个不好的设计,但是现在却无法改变了。

查看英文原文: Covariance and Contravariance in .NET Generics

2008-08-29 01:311451
用户头像

发布了 88 篇内容, 共 263.2 次阅读, 收获喜欢 8 次。

关注

评论

发布
暂无评论
发现更多内容

简述 CAP 原理

叶鹏

从零开始搭建完整的电影全栈系统(五)——WEB网站、Api以及爬虫的部署

刘强西

爬虫 网站搭建 部署与维护

anyRTC云端录制功能上线

anyRTC开发者

WebRTC 语音 直播 RTC 安卓

用户密码验证函数

叶鹏

前端如何优雅处理类数组对象?

Geek_z9ygea

Java 大前端

关于Java调用类的main方法

谷鱼

Java 包位置

Spring 5 中文解析数据存储篇-编程式事物管理

青年IT男

Spring5

架构师训练营第四周作业

叶鹏

一文学懂递归和动态规划!

小齐本齐

算法 数据结构和算法

Spring 5 中文解析数据存储篇-@Transactional使用

青年IT男

spring

架构师训练营第7周作业

叶鹏

两天,我把分布式事务搞完了

yes

分布式事务 seata

一个草根的日常杂碎(9月21日)

刘新吾

生活 现实纪录 随笔

坚持新媒体写作第21天了,聊聊我为什么喜欢写作

老胡爱分享

学习 写作 习惯养成 坚持 随笔杂谈 讨论写作

【性能优化】面试官:Java中的对象都是在堆上分配的吗?

冰河

面试 性能优化 JVM 性能调优 逃逸分析

Python 中 \x00 和空字符串的区别,以及在 Django 中的坑

AlwaysBeta

Python django 编程

简述JVM垃圾回收

叶鹏

微服务的框架(Dubbo)架构

叶鹏

架构师第1课作业及学习总结

小诗

架构师训练营第八周作业

叶鹏

18 张图,一文了解 8 种常见的数据结构

沉默王二

Java 数据结构

实战中学习浏览器工作原理 — 排版与渲染

三钻

CSS 大前端 浏览器

架构师训练营12周作业

叶鹏

常用设计模式

叶鹏

被我玩坏的git:除了之前的工作、当网盘用,还能这么玩

小Q

Java git 程序员 架构 开发

Springboot 定时任务

hepingfly

定时任务 springboot 注解

小白理财先转变思维理念

boshi

理财 收入 财富自由

食堂卡就餐卡系统

叶鹏

oeasy 教您玩转linux 010304 图形界面 xfce

o

ECMAScript 6新特性简介

程序那些事

nodejs ES6 ECMAScript 6

高难度对话读书笔记—情绪篇

wo是一棵草

.NET泛型中的协变与逆变_.NET_Jonathan Allen_InfoQ精选文章