问题标签 [covariance]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
5 回答
1914 浏览

c# - 为什么我们需要 C# 中协变和逆变的新关键字?

有人可以解释为什么需要添加 out 或 in 参数来指示泛型类型是 C# 4.0 中的 Co 或 Contra 变体吗?

我一直在试图理解为什么这很重要以及为什么编译器不能弄清楚..

谢谢,

乔什

0 投票
4 回答
3287 浏览

class - 关于类继承的协变与逆变

“协变”和“逆变”这两个概念的含义是什么?

给定 2 个类AnimalElephant(从Animal继承),我的理解是,如果您尝试将 Elephant 放入 Animals 数组中,您会遇到运行时错误,这是因为 Elephant 是“更大”(更多具体)比动物。但是,您能否将 Animal 放入 Elephant 数组中,看看 Elephant 是如何保证包含 Animal 属性的?

0 投票
2 回答
2015 浏览

c# - 泛型类中的 C#-数组协方差

我知道 C# 支持这样的数组中的协方差:

但是当它尝试编译以下代码时出现错误

它说“无法将类型'T[]'隐式转换为'K[]'”

为什么我收到这个错误???

0 投票
2 回答
1908 浏览

c# - 在 C# 4.0 中,为什么方法中的 out 参数不能是协变的?

鉴于这个神奇的界面:

而这个类层次结构:

我现在可以编译这个:

这是伟大的。但是如果我以不同的方式定义接口怎么办:

我表示帽子可能是空的,使用单独的布尔返回值(以前的版本可能会从空帽子返回空兔子)。但我仍然只输出一只兔子,所以没有做任何与以前版本在逻辑上不同的事情。

CTP 中的 C# 4.0 编译器在接口定义中给出错误 - 它要求“out”方法参数为不变类型。是否有一个明确的理由为什么不允许这样做,或者它可能会在未来的版本中解决?

0 投票
5 回答
15984 浏览

c# - 从 IEnumerable 强制转换 to IEnumerable

Recently I found a very surprising behavior in c#. I had a method which takes IEnumerable<Object> as a parameter and i was passing IEnumerable<string>

Recently I found a very surprising behavior in c#. I had a method which takes IEnumerable<Object> as a parameter and i was passing IEnumerable<string> but it's not possible. While in c# everything can be upcast to Object than why this is not possible? It's totally confusing for me. Please someone clear me on this issue.


The technical term for this is that generics are invariant in C# 3.0 and earlier. From C#4.0 onward, the cast works.

What invariant means is that there is no relationship between two generic types just because their generic type parameters are related (i.e. are sub- or supertypes of each other).

In your example, there is no typing relationship between an IEnumerable<object> and an IEnumerable<string>, just because string is a subtype of object. They're just considered two completely unrelated types, like a string and an int (they still both are subtypes of object, but everything is)

There are a few workarounds and exceptions for this issue you've run into.

First, you can cast each string individually to object, if you're using .NET 3.0 you can do that using the Cast<T>() extension method. Otherwise, you can use a foreach and put the result into a new variable of the static type you want.

Second, arrays are an exception for reference type, i.e. passing in a string[] type to a method acccepting object[] types should work.

0 投票
6 回答
7525 浏览

c++ - C++ 协变模板

我觉得以前有人问过这个问题,但是我在 SO 上找不到它,在 Google 上也找不到任何有用的东西。也许“协变”不是我要找的词,但这个概念与函数的协变返回类型非常相似,所以我认为它可能是正确的。这是我想做的,它给了我一个编译器错误:

假设这些课程完全充实......我想你明白了。由于某些不清楚的原因,它无法将 a 转换SmartPtr<Derived>为 a 。SmartPtr<Base>我记得这在 C++ 和许多其他语言中很正常,但目前我不记得为什么。

我的根本问题是:执行此分配操作的最佳方法是什么?目前,我将指针从 中拉出SmartPtr,显式地将其向上转换为基本类型,然后将其包装在SmartPtr适当类型的新类型中(请注意,这不会泄漏资源,因为我们的本土SmartPtr类使用侵入式引用计数)。那很长而且很乱,尤其是当我需要将其包装SmartPtr在另一个对象中时……有什么快捷方式吗?

0 投票
1 回答
14690 浏览

java - Scala中变量声明中的通用通配符

在 Java 中,我可能会这样做:

...假设(MyImpl implements MyInterface)当然。

使用Scala中的类似物是Buffer什么?

这(当然)不会编译 - 但是我如何list以这样的方式声明变量呢?

编辑;我再补充一点。区别显然与以下事实有关:在 Java 中,泛型在 T 中永远不会协变,而在 Scala 中,它们可以是协变的,也可以不是协变的。例如,Scala 类List在 T 中是协变的(并且必然是不可变的)。因此以下将编译

我仍然在为编译器错误苦苦挣扎:

Covariant type T occurs in contravariant position in ...

例如; 此编译器错误发生在类声明中:

我要问一个单独的问题...

0 投票
4 回答
31815 浏览

generics - 为什么示例不编译,也就是(co-,contra-和in-)方差如何工作?

this question之后,有人可以在Scala中解释以下内容:

+T我理解类型声明中和之间的区别T(如果我使用它会编译T)。但是,如何在不诉诸于创建未参数化的事物的情况下,实际编写一个类型参数协变的?如何确保只能使用 的实例创建以下内容T

编辑-现在将其归结为以下内容:

这一切都很好,但我现在有两个类型参数,我只想要一个。我将重新提出这个问题:

如何编写一个类型协变的不可变 Slot类?

编辑2:呃!我用过var,没有val。以下是我想要的:

0 投票
3 回答
8309 浏览

scala - 为什么 Scala 的不可变 Set 在其类型上不是协变的?

编辑:根据原始答案重新编写了这个问题

该类scala.collection.immutable.Set的类型参数不是协变的。为什么是这样?

0 投票
1 回答
374 浏览

scala - Scala API 设计;返回一个集合的服务,其中我是某个接口(抽象/特征)