写点什么

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

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

关注

评论

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

企业如何添加内嵌式的帮助文档

Baklib

帮助文档

docker学习笔记

正向代理与反向代理

急需上岸的小谢

10月月更

Spring事务传播机制

急需上岸的小谢

10月月更

Ubuntu 设置中文语言环境

Yeats_Liao

ubuntu 后端 10月月更

【kafka原理】kafka Log存储解析以及索引机制

石臻臻的杂货铺

kafka 10月月更

eeui安卓开发--如此简单

江拥羡橙

android Weex 安卓 10月月更

Spring Boot「10」Propety 验证

Samson

Java spring 学习笔记 spring-boot 10月月更

一起学习 Go 语言设计模式之建造者模式

宇宙之一粟

设计模式 建造者模式 Go 语言 10月月更

Mybatis学习

Studying_swz

10月月更

【kafka原理】 消费者偏移量__consumer_offsets_相关解析

石臻臻的杂货铺

kafka 10月月更

Databend 存储架构总览

Databend

【kubernetes技术专题】Kubernetes架构分析介绍篇(入门篇)

洛神灬殇

Kubernetes k8s Kubernetes Serverless 10月月更

Linux学习-权限的理解

可口也可樂

后端 Linux Kenel linux 文件权限控制 10月月更

leetcode 450. Delete Node in a BST 删除二叉搜索树中的节点 (中等)

okokabcd

LeetCode 数据结构与算法

促双碳|AIRIOT智慧能源管理解决方案

AIRIOT

物联网 智慧能源

ios苹果打包——超详细的教程分享

江拥羡橙

ios CocoaPods 苹果 Weex 10月月更

Spring IOC和AOP

Studying_swz

spring 10月月更

Glibc---_IO_do_write函数逻辑分析

桑榆

源码刨析 10月月更 C++

spring用到的设计模式

急需上岸的小谢

10月月更

一文带你入门微服务,通俗易懂

wljslmz

架构 微服务 10月月更 单体服务

前端JavaScript小技巧【建议收藏】

江拥羡橙

JavaScript ES6 10月月更

Linux学习-开发工具yum/vim/gcc/g++/gdb

可口也可樂

开发工具 Linux Kenel 10月月更

YARN工作流程

穿过生命散发芬芳

YARN 10月月更

成功建设私有云需要考虑这些关键点

阿泽🧸

私有云 10月月更

【Java深入学习】一个关于“锁”的程序-中

Geek_65222d

10月月更

程”风破浪的开发者|个人信息管理

CODA

学习方法 信息管理 10月月更 “程”风破浪的开发者

Linux学习-常用指令

可口也可樂

后端 Linux Kenel 10月月更

“程”风破浪的开发者|国产之光,鸿蒙系统

急需上岸的小谢

OpenHarmony “程”风破浪的开发者

Node.js入门

Studying_swz

Node 10月月更

2022-10-21:你将得到一个整数数组 matchsticks ,其中 matchsticks[i] 是第 i 个火柴棒的长度。 你要用 所有的火柴棍 拼成一个正方形。 你 不能折断 任何一根火柴

福大大架构师每日一题

算法 rust 福大大

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