问题标签 [contravariance]

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 投票
2 回答
2052 浏览

scala - 逆变的例子

我正在考虑以下示例来说明为什么逆变是有用的。

让我们考虑一个带有WidgetsEvents和的 GUI 框架Event Listeners

让我们Widgets定义以下方法:

这些方法只接受“特定”事件侦听器,这很好。但是,我还想定义“厨房水槽”侦听器,它侦听所有事件,并将此类侦听器传递给上面的“添加侦听器”方法。

例如,我想定义LogEventListener记录所有传入事件

由于 traitEventListener逆变的,Event我们可以传递LogEventListener给所有这些“添加侦听器”方法,而不会失去它们的类型安全性。

是否有意义 ?

0 投票
3 回答
295 浏览

c# - 无法在 C# 中使用协方差/反方差

无法确定条件表达式的类型,因为“ConsoleApplication4.E”和“ConsoleApplication4.C”之间没有隐式转换

现在我明白了“为什么”(我认为),但我看不出如何编译。我想我必须创建一个定义某种方差并从中继承的接口,但我不确定。但无论如何,E()都应该继承自C().

有接盘侠吗?

TIA

0 投票
1 回答
490 浏览

.net - 带有强制转换异常的 C# .NET 4.0 通用协方差问题

我已经为此奋斗了一段时间,所以任何帮助将不胜感激。这是我在 C# .NET 4.0 上遇到的情况。

我有一个实现两个接口的对象。代码编译得很好。但是在运行时,我可以按如下方式转换此对象:

但不是这样:

这非常令人困惑,我不确定我做错了什么。有人请指出我正确的方向。谢谢!

0 投票
3 回答
228 浏览

c# - 不变继承问题

我正在尝试实施一种策略模式,以允许我将一些“好处”应用于“帐户”。在下面的代码中,我无法将接口的实现添加到期望该接口的字典中。我认为这是某种逆变问题,但感觉我应该能够做到这一点:

编辑:
由于答案似乎是不可能的,关于如何实现我在这里的目标有什么建议吗?

0 投票
2 回答
728 浏览

c# - 使用通用接口约束时的协方差/逆变难题

鉴于上面的代码,编译器无法确定如何将类型分配MyFooIFoo<IShape, Base>,大概是因为U设置为 out 意味着它可以接受更少的派生。但是,Derived是 比 更派生Base,因此会产生编译器错误。

这个例子是人为的,但我们正在处理的实现是MyFoo从工厂返回的。

虽然U用作参数,但在尝试将其分配给通用接口时它也是一个输出,但我无法在out此处使用关键字。我们如何解决这个问题?

0 投票
2 回答
673 浏览

java - 通配符类型的协变和逆变

您能否解释一下为什么可以这样做:

我不明白,为什么不能将某些内容添加到协变列表 la,但仍然可以将 B 添加到逆变列表 lb - 但不能将 A 添加到 lb。

从我的角度来看,应该可以将扩展 A 的所有内容添加到列表中。我可以看到不这样做的唯一原因,因为很容易将 C 添加到 B 列表中,例如

逆变可能也是如此,例如

我不明白的 - 为什么不可能做

很明显,在这个阶段,C 的超类是 B 类——Java 不允许多重继承。

还有为什么它禁止

我不清楚。

0 投票
1 回答
770 浏览

c# - 让 Unity 解决考虑逆变的实现

我想将统一用于多态事件聚合/处理,其中处理程序通过容器注册。

处理程序使用“in”修饰符声明一个通用参数,因为它仅用作输入参数。所以参数是逆变的。

考虑以下示例。

我的期望如下:

  • 如果我收到一个MsgA,我应该将它发送到MsgAHandler,MsgHandlerObjectHandler
  • 如果我收到 a IMsg,我应该将它发送到MsgHandlerand ObjectHandler
  • ObjectHandler应该收到所有消息。

默认情况下,Castle Windsor 可以在没有任何特定配置的情况下正确处理这种情况(使用 v2.5.1 测试)。

Unity 是否公开了一种提高分辨率并允许Resolve<IHandle<MsgA>>()匹配任何类型实现IHandle<IMsg>的方法IHandle<object>

我已经使用 UnityExtensions(匹配规则、策略等)寻找示例,但没有成功。

有人可以指导我使用正确的机制来实现这样的场景吗?

0 投票
1 回答
166 浏览

c# - 关于方法参数中使用逆变参数的问题

我读过一篇介绍协方差和协方差的好文章

http://bartdesmet.net/blogs/bart/archive/2009/04/15/14377.aspx

逆变参数只应出现在输入位置:方法参数、仅设置属性或索引器。

根据我对逆变的理解,我把代码放在上面。显然,线 A 不正确,我误解了逆变的概念。

哪一部分是错的?什么概念没有正确理解?如何使它正确?

0 投票
1 回答
353 浏览

c# - 现实世界数组协方差问题

我正在尝试创建一个 DataTableColumn 类的数组,但不幸的是我为此发疯了。到目前为止,这就是我试图做的但没有成功

我的数组应该像

实际上是这样工作的

我认为使用动态并不是最好的方法......请有人阐明!

编辑

该死的我忘记了错误

无法将类型 DataTableColumn< int >' 隐式转换为 'IDataTableColumn< object >'。存在显式转换(您是否缺少演员表?)

无法隐式转换类型 DataTableColumn< System.DateTime?>' 到 'IDataTableColumn< 对象 >'。存在显式转换(您是否缺少演员表?)

0 投票
3 回答
1736 浏览

c# - IComparer 和 IEqualityComparer 接口中逆变的好处

在有关逆变的msdn 页面上,我发现了一个非常有趣的示例,它显示了“IComparer 中逆变的好处”

首先,他们使用了一个相当奇怪的基类和派生类:

我已经可以说这是一个不好的例子,因为没有一个类只是继承一个基类而不添加至少一点它自己的东西。

然后他们创建了一个简单的 IEqualityComparer 类

接下来是有问题的示例。

现在我的问题 - 首先在这种情况下 Employee 是一个不需要的类,它确实可以在这种情况下使用 PersonComparer 因为它实际上只是一个人类!

然而,在现实世界中Employee,至少会有一个新领域,比如说JobTitle. 鉴于很明显,当我们想要区分员工时,我们需要考虑 JobTitle 字段进行比较,并且很明显,逆变比较器(例如人员比较器)不适合该工作,因为它不知道任何新成员员工已定义。

当然,任何语言特性,即使是一个非常奇怪的特性,都可以有它的用途,即使它在某些情况下是不合逻辑的,但在这种情况下,我认为它不会太频繁地成为默认行为。事实上,在我看来,因为我们有点破坏类型安全,当一个方法需要一个 Employee 比较器时,我们实际上可以放入一个人甚至对象比较器,它会毫无问题地编译。虽然很难想象我们的默认方案是将 Employee 视为对象..或基本 Person。

那么这些接口的默认逆变器真的是一个很好的逆变器吗?

编辑:我明白什么是逆变和协方差。我在问为什么那些比较接口被更改为默认逆变。