写点什么

.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:311565
用户头像

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

关注

评论

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

Bonree ONE 2.0重磅发布,中国IT运维迈入数智融合3.0时代

博睿数据

可观测性 根因分析 博睿数据 ONE平台 智能运维AIOps

从零开始实现一个Promise

helloworld1024fd

JavaScript

golang中经常会犯的一些错误

六月的

golang

golang中的errgroup

六月的

golang errgroup

golang开发一个简单的grpc

六月的

golang gRPC

vue为什么v-for的优先级比v-if的高?

bb_xiaxia1998

Vue

揭秘百度智能测试在测试评估领域实践

百度Geek说

测试 数据 企业号十月 PK 榜

golang中的socket编程

六月的

golang socket

CORS跨域

六月的

CORS

一键上手时下最火AI作画工具

华为云开发者联盟

人工智能 华为云

vue组件通信6种方式总结(常问知识点)

bb_xiaxia1998

Vue

grpc中的拦截器

六月的

gRPC 拦截器

进阶vue面试题总结

bb_xiaxia1998

Vue

@全体开发者, 华为云1024程序员节精彩开启!

华为云开发者联盟

华为云 企业号十月 PK 榜

社招前端经典手写面试题合集

helloworld1024fd

JavaScript

MobLink Android 快速集成

MobTech袤博科技

Gradle sdk moblink

Vue组件入门(九)v-model 自定义修饰符

Augus

Vue 3 10月月更

Git的branch操作详解

timerring

git 10月月更 branch

固定QPS异步任务功能初探

FunTester

100+款AI产品薅羊毛攻略(上)——轻轻松松节省几十万

夏夜许游

人工智能 阿里云 AI 视觉

golang中的变量阴影

六月的

golang

将 NGINX 部署为 API 网关,第 2 部分:保护后端服务

NGINX开源社区

nginx 安全 Backend Developer api 网关 模块

数字化的一切都会在安全沙箱里面

FN0

云计算 安全性 沙箱

从零手写react-router

helloworld1024fd

JavaScript

golang垃圾回收

六月的

golang 垃圾回收

grpc错误处理

六月的

gRPC 错误处理

如何修改已提交commit信息

Appleex

git

链表专项之环形链表

lovevivi

c 数据结构 10月月更

golang中的一些实用功能

六月的

golang

PaddleNLP基于ERNIR3.0文本分类:WOS数据集为例(层次分类)

汀丶人工智能

nlp 文本分类

EasyNLP发布融合语言学和事实知识的中文预训练模型CKBERT

阿里云大数据AI技术

深度学习 开源 语言模型 企业号十月PK榜

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