首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >方差、通用接口和输入/输出之间的关系是什么?

方差、通用接口和输入/输出之间的关系是什么?
EN

Software Engineering用户
提问于 2022-11-26 22:47:28
回答 1查看 778关注 0票数 3

有一个由Eric编写的博客帖子,他在这里描述了如何定义方差。在一般意义上,当赋值兼容性的方向保持不变时,就实现了协方差。当分配兼容性的方向被逆转时,就实现了反方差。

现在,让我们以一个C#通用接口为例。请考虑简单地说,C#中的以下代码:

代码语言:javascript
运行
复制
IPoppable<Animal> animals = bears;
Animal a = animals.Pop();

public interface IPoppable<out T> { T Pop(); }
public interface IPushable<in T> { void Push (T obj); }

class Animal {}
class Bear : Animal {}
class Camel : Animal {}

public class Stack<T> : IPoppable<T>
{
  int position;
  T[] data = new T [100];
  public void Push (T obj) => data [position++] = obj;
  public T Pop()           => data [--position];
}

IPoppable接口使用<out T>表示只能在输出位置使用T。这在示例代码的上下文中是有意义的。由于Stack<T>类继承自IPoppable<out T>,因此Pop()只应从堆栈返回数据。它不应将数据作为输入添加。

因此,上面的代码说明了如何使用out参数实现与一般接口的协方差。out参数将Pop()方法限制为仅在输出位置使用T

可以使用in参数实现反向操作,这将允许我们通过将T限制在泛型接口中的输入位置来实现逆方差。上面的IPushable接口显示了这一点。

考虑到所有这些,将类型限制在输出位置如何与Eric Lippert的定义有关,即在保持分配兼容性时定义协方差?类似地,将类型参数限制在输入位置与反方差的定义有什么关系?

EN

回答 1

Software Engineering用户

发布于 2022-12-05 18:04:43

你已经有两个好答案了,让我提供一个更简洁的第三个答案。让我们从重新陈述这个问题开始:

将类型限制在输出(或输入)位置如何实现分配兼容性关系的保留(或逆转)?

关键的洞察力在于思考一个简单的函数。让我们假设每一个哺乳动物都有一个朋友,他也是哺乳动物。

代码语言:javascript
运行
复制
static Dictionary<Mammal, Mammal> friends = whatever;
static Mammal F (Mammal input) => friends[input];

问题是:我们如何在法律上改变(变化!)F的类型签名而不更改主体或friends的声明?(忽略F的任何现有调用者;我们只关心F的主体是否合法。)

代码语言:javascript
运行
复制
static Mammal F (Animal input) => friends[input];  
// WRONG, we could pass a Turtle
static Mammal F (Giraffe input) => friends[input];  
// RIGHT, this is fine
static Animal F (Mammal input) => friends[input];  
// RIGHT, this is fine
static Giraffe F (Mammal input) => friends[input];  
// WRONG, it might return a Tiger

结论是,像Func<Mammal, Mammal>这样的F总是可以在需要Func<Giraffe, Animal>的上下文中使用,但不能在需要Func<Animal, Giraffe>的上下文中使用。

这就是为什么协方差和输出以及反向方差和输入之间有联系的原因。它是从关于功能体如何工作的基本事实中得出的。使输出类型声明更大或输入类型声明更小,保持主体的正确性。

票数 4
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/442469

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档