问题标签 [invariance]
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# - C#中同一列表中的逆变或不变接口
我遇到了一个关于接口协变和逆变的问题。我有两个通用接口:
IConfiguration 只是一个空接口(标记)。还有第三个界面:
我想要一个包含所有 IConfigurable 实现的列表(无论 T 的具体类型如何)。因为 IConfigProvider 是协变的,所以我可以有一个 IConfigProviders 列表,但 IConfigConsumer 是不变的,所以我不能有这样的列表:
最好有一个列表,IConfigurable<IConfiguration>
因为我需要在两个接口中定义的功能。
我只是找不到办法做到这一点。
一种解决方法可能是去掉 IConfigConsumer 接口中的 type 参数并定义 Load 方法,如下所示:
但这会稍微“伤害”类型安全性,因为我可以将类型 ConfigA 加载到需要 ConfigB 的 ConfigConsumer 中,并且只有在我尝试在 Load 方法中将其强制转换为 ConfigB 时,它才会在运行时抛出异常。
这是我的完整示例代码:
我开始怀疑我想要的甚至是可能的。你有什么主意吗?预先感谢您的所有帮助!
scala - Scala - 可变集合中的协变类型
我是 Scala 世界的新手,现在我正在阅读名为“Scala in Action”的书(Nilanjan Raychaudhuri 着),即第 97 页上名为“可变对象需要保持不变”的部分,我不明白以下部分直接取自上述书中。
假设 ListBuffer 是协变的,并且以下代码片段可以正常工作,没有任何编译问题:
你能发现问题吗?因为一切都是 Any 类型,所以您可以将整数值存储到字符串集合中。这是一场等待发生的灾难。为了避免这类问题,让可变对象保持不变总是一个好主意。
我会有以下问题..
1)everything
现实中是什么类型?String
还是Any
?声明是“ val everything: ListBuffer[Any]
”,因此我会期望Any
,因为一切都应该是类型,Any
那么我看不出有Integer
任何String
问题ListBuffer[Any]
。如何将整数值存储到字符串集合中,它们是如何编写的???何为灾难???为什么我应该使用 List(它是不可变的)而不是 ListBuffer(它是可变的)?我看不出有什么区别。我找到了很多答案,可变集合应该具有类型不变,不可变集合应该具有协变类型,但为什么呢?
2)最后一部分“ res4: everything.type = ListBuffer(1, pants)
”是什么意思?“everything.type”是什么意思?我猜它everything
没有任何方法/函数或变量称为type
.. 为什么没有 ListBuffer[Any] 或 ListBuffer[String]?
非常感谢,
安德鲁
generics - Kotlin 泛型类属性
我知道这似乎是一个重复的问题,但我对不变性、协变和逆变如何工作感到困惑。
我不明白为什么我不能编译这个片段:
我收到类型不匹配错误必需 X 找到列表
但是,如果我将 X 泛型定义为“out”,我将收到一个错误,表明参数 X 在 list1 var 中是不变的。
有人可以帮助另一个迷失在 Kotlin 泛型中的可怜的灵魂吗?
c# - 为什么这个具体的泛型类型不能被履行相同契约的具体类型所取代?
为什么在实现class Node
中泛型类型IEdge<Node>
不能被具体实现所取代class Edge:IEdge<Node>
。
TEdgeN
用作输入参数void AddIncoming(TEdgeN edge)
以表明在这种情况下out TEdgeN
不能解决问题。否则,这可以使用 来解决out TEdgeN
,这将允许一个covariant
类型TEdgeN
。
虽然上述,IEdge<NodeGood>
对于类型TEdgeN
是有效的,我想知道为什么EdgeBad
是一个无效的类型TEdgeN
,例如:
我完全清楚,我正在监督一些事情,但不应该:
TEdgeN
是in的有效类型
我敢肯定,但假设编译器会抱怨,因为解析中INode
和 IEdge
解析时的循环泛型约束NodeBad
:
- 要验证
NodeBad
是 的有效类型TNodeN
,它需要知道EdgeBad
是 的有效类型TEdgeN
- 要验证
EdgeBad
是 的有效类型TEdgeN
,它需要知道这NodeBad
是 的有效类型TNodeE
- 要验证
NodeBad
它是一个有效的类型,TNodeE
它需要它是一个有效的类型,TNodeN
因为TNodeE
它被用作TNodeN
约束中的类型interface IEdge
arrays - 大批: 获取和设置 Int 值而不进行强制转换
我正在构建一个 Matrix 类,并希望能够将Number
s 存储在二维数组中。
这不起作用,因为Array<Number>
并且Array<Int>
是不变的。我可以通过使用使其工作Array<Array<out Number>>
,但 Matrix 将是不可变的,我不希望这样......
强制转换{0 as Int}
使编译器错误消失,但这似乎不是一个好主意。我也想做加法之类的事情,我注意到不可能添加Number
s:
那么我该如何解决这个问题呢?为什么我不能添加两个Number
s?
scala - 在 State 中绕过不变的结果类型
我想定义一个State
构建特征的具体子类型的,根据decodeFoo
:
这不会像 catState
中定义的那样type State[S, A]
编译,编译器会响应:
decodeBar
我可以通过将&的定义扩大decodeBaz
到 type 来解决这个问题State[Seq[Byte], Foo]
。这是最好的前进方式吗?或者我可以采取不同的方法来避免扩大这些类型吗?
scala - Scala 类型差异
我有以下代码
所以最后一个错误不是预期的,但是如果我让它A
成为协变的,它就会出错,因为我可以说
这很令人困惑,所以我可以接受。
那么此时,如何去掉最后一个错误,让编译器明白 aWarrior
是 aPerson
呢?
c# - 无法在列表 c# 中保存通用接口实现
如何使列表包含通用接口的所有不同实现?
例如
我想把所有的捕手放在一个类似的列表中,
我知道这是处理 c# 中的泛型修饰符(协变、逆变和不变性)但无法让它工作的东西。
尝试:在中添加“out”
但给出编译时错误:
“类型参数 'T' 必须在 'ICatcher.Catch(T)' 上逆变有效。'T' 是协变的。”
我究竟做错了什么?
php - 这是使用 php 7 断言的类不变性的有效示例吗?
我试图更好地理解 Liskov 原则使用的类不变性。
我知道像 D 这样的一些语言对 invariant 有本机支持,但是,在 PHP 中使用断言我尝试将魔法方法和断言结合起来:
- 我可以使用断言来创建合同吗?
- BadPerson 是 Liskov 对继承的 Class Invariance 违反的有效示例吗?
- GoodPerson 是 Liskov 的类不变性的有效例子吗?
generics - Kotlin 中的方差/协方差泛型
有一个密封类 Result,它被参数化为两种类型 - 成功结果(T)和错误类型(R)。
它由两个类继承:
一个。Success - 数据类,在构造函数中接受对象 T
湾。错误 - 数据类,在构造函数中接受对象 R
我需要创建一个返回 Result 对象的函数。该函数必须以某种方式创建:
- 该函数的结果可以分配给以下类型的变量:
- 该函数的结果不能分配给以下类型的变量:
即类 Result 必须在 T 参数上是协变的,在 R 参数上是不变的。