问题标签 [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.
c# - 继承需要存储子类特定数据的数组的最佳方法是什么?
我正在尝试设置类似于以下的继承层次结构:
我只想将 MotorcycleAxle 对象存储在 Motorcycle 对象的 Axles 数组中,并将 CarAxle 对象存储在 Car 对象的 Axles 数组中。问题是没有办法覆盖子类中的数组来强制其中一个。理想情况下,类似以下内容对 Motorcycle 类有效:
但是覆盖时类型必须匹配。我怎样才能支持这种架构?我是否只需要在访问 Axles 成员的任何地方进行大量运行时类型检查和转换?我不喜欢添加运行时类型检查,因为您开始失去强类型和多态性的好处。在这种情况下必须至少进行一些运行时检查,因为 WheelAttached 和 Left/RightWheelAttached 属性取决于类型,但我想最小化它们。
c# - 为什么继承不能像我认为的那样工作?
我遇到了一些继承问题,因为我有一组相互关联的抽象类,需要一起重写以创建客户端实现。理想情况下,我想做以下事情:
这将允许任何使用 Dog 类的人自动获取 DogLegs 并允许任何使用 Animal 类的人获取 Legs。问题是被覆盖的函数必须与基类具有相同的类型,因此无法编译。我不明白为什么不应该这样做,因为 DogLeg 可以隐式转换为 Leg。我知道有很多方法可以解决这个问题,但我更好奇为什么这不可能/在 C# 中实现。
编辑:我对此进行了一些修改,因为我实际上是在代码中使用属性而不是函数。
编辑:我把它改回函数,因为答案只适用于那种情况(属性的 set 函数的 value 参数的协方差不应该起作用)。波动请见谅!我意识到这让很多答案看起来无关紧要。
c# - C# 4.0 中如何实现泛型协方差和逆变换?
我没有参加 PDC 2008,但我听说 C# 4.0 宣布支持通用协变和逆变换的消息。也就是说,List<string>
可以分配给List<object>
。怎么可能?
在 Jon Skeet 的C# in Depth一书中,解释了为什么 C# 泛型不支持协变和逆变。它主要用于编写安全代码。现在,C# 4.0 更改为支持它们。会不会带来混乱?
有人知道有关 C# 4.0 的详细信息可以给出一些解释吗?
c# - 为什么我们需要 C# 中协变和逆变的新关键字?
有人可以解释为什么需要添加 out 或 in 参数来指示泛型类型是 C# 4.0 中的 Co 或 Contra 变体吗?
我一直在试图理解为什么这很重要以及为什么编译器不能弄清楚..
谢谢,
乔什
class - 关于类继承的协变与逆变
“协变”和“逆变”这两个概念的含义是什么?
给定 2 个类Animal和Elephant(从Animal继承),我的理解是,如果您尝试将 Elephant 放入 Animals 数组中,您会遇到运行时错误,这是因为 Elephant 是“更大”(更多具体)比动物。但是,您能否将 Animal 放入 Elephant 数组中,看看 Elephant 是如何保证包含 Animal 属性的?
java - 覆盖 Java 泛型方法
我想创建一个用于将对象复制到同一类的目标对象的接口。简单的方法是使用强制转换:
但我也找到了一种可以使用泛型完成的方法:
虽然我发现摆脱警告的唯一方法是注释。而且感觉好像出了点问题。那么有什么问题呢?我可以接受问题的根源有问题。因此,欢迎任何形式的澄清。
java - Scala中变量声明中的通用通配符
在 Java 中,我可能会这样做:
...假设(MyImpl implements MyInterface
)当然。
使用Scala中的类似物是Buffer
什么?
这(当然)不会编译 - 但是我如何list
以这样的方式声明变量呢?
编辑;我再补充一点。区别显然与以下事实有关:在 Java 中,泛型在 T 中永远不会协变,而在 Scala 中,它们可以是协变的,也可以不是协变的。例如,Scala 类List
在 T 中是协变的(并且必然是不可变的)。因此以下将编译:
我仍然在为编译器错误苦苦挣扎:
Covariant type T occurs in contravariant position in ...
例如; 此编译器错误发生在类声明中:
我要问一个单独的问题...
generics - 为什么示例不编译,也就是(co-,contra-和in-)方差如何工作?
继this question之后,有人可以在Scala中解释以下内容:
+T
我理解类型声明中和之间的区别T
(如果我使用它会编译T
)。但是,如何在不诉诸于创建未参数化的事物的情况下,实际编写一个类型参数协变的类?如何确保只能使用 的实例创建以下内容T
?
编辑-现在将其归结为以下内容:
这一切都很好,但我现在有两个类型参数,我只想要一个。我将重新提出这个问题:
如何编写一个类型协变的不可变 Slot
类?
编辑2:呃!我用过var
,没有val
。以下是我想要的:
c#-3.0 - 我应该在 C#3.0 中支持 Pub-/Sub-Scenarios 的 Co-/Contravariance 吗?
在我的应用程序中,我正在创建一个简单的事件中心,它为注册订阅者提供了一些东西:
并用于发布事件。
非常简单。我想路由Publish<int>(0)
到所有实现的订阅者ISubscriber<int>
.
不太难的是,我希望订阅者 EventType 是逆变的。所以ISubscriber<object>
基本上应该消耗掉一切。我不希望他们也使用值类型。
用 C#4 没问题,但现在我用 C#3 做这些事情,只是用接口假装逆变:
好吧,现在,我想像这样将数据打包成“事件类型”。该事件的通用参数必须是协变的。
当我发布Publish<DataChanged<B>>(new DataChanged<B>(new B())
(给定 B:A)时,应通知订阅者DataChanged<A>
Data 是传递给的 B 实例的位置DataChanged<B>
。所以我也需要协方差支持。
我想编写一个支持 Co-/和逆变的库,如下所示:
这将允许像这样的转换(不是强制转换!):
你怎么看?可能吗?考虑使用动态代理来做这件事。