问题标签 [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 投票
2 回答
254 浏览

java - 在编译器或类型检查器 (javac) 中导致堆栈溢出的 Java 片段?

昨天在一次研讨会上,演讲者 (Peter Sestoft) 展示了一个小型 java 程序,有 3 个类,同时具有协变和逆变。尝试使用 javac 编译时,类型检查器将抛出 StackOverflowException。

该片段是由一些在微软工作的人开发的(想想一个叫做肯尼迪)。

用谷歌找不到。有谁知道代码片段,你能把它贴在这里(最多10行代码)给大家看吗?:)

这很有趣……

0 投票
12 回答
130332 浏览

c# - 转换列表列出

虽然我们可以从基类/接口继承,但为什么我们不能声明一个List<> 使用相同的类/接口?

有办法吗?

0 投票
3 回答
7283 浏览

inheritance - 扩展扩展有序的 scala 类

我无法扩展扩展 Ordered[Base] 的基类。我的派生类不能扩展 Ordered[Derived] 所以不能用作 TreeMap 中的键。如果我创建一个 TreeMap[Base] ,然后在 Derived 中覆盖比较有效,但这不是我想要的。我希望能够将派生类作为键。有没有解决的办法?

编辑

scala 邮件列表上的这个讨论似乎非常相关,但它让我有点失落。

0 投票
2 回答
137 浏览

generics - 基于 IEnumerable 的类型推断

已经有一些关于这种事情的堆栈溢出帖子,但并不完全相同 - 如果这是已经回答的问题,请提前道歉。

为什么这不起作用:

如果我在上面调用 Go() 并传入 MyBase 对象的负载,每次对 Foo 的调用都会调用通用的 Foo(),它返回 true。

为什么它不调用专门的 MyBase 版本呢?如果我直接调用 Foo (new MyBase ()) ,它会正确推断出要进行的调用。这是因为 C#3 中的集合缺乏协方差,还是我只是很傻,没有正确地做到这一点?

谢谢!

艾萨克

0 投票
9 回答
81530 浏览

java - 什么是协变返回类型?

Java中的协变返回类型是什么?在一般的面向对象编程中?

0 投票
2 回答
751 浏览

c# - C# 3 中具有接口继承(co(ntra)-variance?)的泛型类型推断

我有以下两种通用类型:

现在我想为这些接口的集合定义一个扩展方法,因为它们都是或者是它们的IRange<T>后代,IRange<T>我希望我可以定义一个可以处理这两者的方法。请注意,该方法不需要处理两者之间的任何差异,只需处理来自IRange<T>.

我的问题是这样的:

我可以定义一个扩展方法来处理IEnumerable<T>这两种类型中的任何一种的集合()吗?

我试过这个:

然而,传递一个IEnumerable<IRange<Int32, String>>,像这样:

给了我这个编译器错误:

错误 1“System.Collections.Generic.IEnumerable>”不包含“Slice”的定义,并且找不到接受“System.Collections.Generic.IEnumerable>”类型的第一个参数的扩展方法“Slice”(你是缺少 using 指令或程序集引用?) C:\Dev\VS.NET\LVK\LVK.UnitTests\Core\Collections\RangeTests.cs 455 26 LVK.UnitTests

注意:我没想到它会编译。我对 co(ntra)-variance 有足够的了解(总有一天我需要知道哪个是哪个方式)知道那是行不通的。我的问题是我是否可以对 Slice 声明做任何事情以使其发挥作用。

好的,然后我尝试推断范围接口的类型,这样我就可以处理所有类型,IEnumerable<R>只要有R问题是IRange<T>.

所以我尝试了这个:

这给了我同样的问题。

那么,有没有办法调整这个?

如果没有,我唯一的选择是:

  1. 定义两个扩展方法,并在内部调用一个内部方法,可能是通过将其中一个集合转换为包含基本接口的集合?
  2. 等待 C# 4.0?

以下是我设想定义这两种方法的方式(注意,我仍处于早期设计阶段,所以这可能根本不起作用):


这是一个显示我的问题的示例程序代码。

请注意,通过在 Main 方法中将调用从 Slice1 更改为 Slice2 会使两种用法都产生编译器错误,因此我的第二次尝试甚至没有处理我最初的情况。

0 投票
5 回答
21457 浏览

c# - 逆变解释

首先,我已经阅读了许多关于 SO 的解释以及关于协变和逆变的博客,非常感谢Eric Lippert制作了这么多关于变和逆变的系列。

但是,我有一个更具体的问题,我想稍微了解一下。

据我了解,Eric 的解释是 Covariance 和 Contravariance 都是描述转换的形容词。协变变换是保留类型顺序的变换,而逆变变换是反转它的变换。

我以我认为大多数开发人员直观理解的方式理解协方差。

这里的返回操作是协变的,因为我们保留了两个 Animal 仍然大于 Mammal 或 Giraffe 的大小。关于这一点,大多数返回操作都是协变的,逆变操作没有意义。

对于大多数开发人员来说,这段代码当然没有意义。

我的困惑在于逆变参数参数。如果你有一个方法,比如

我一直都知道输入参数总是强制逆变行为。这样,如果将类型用作输入参数,则其行为应该是逆变的。

但是下面的代码有什么区别

出于同样的原因,你不能做这样的事情你不能做

我想我要问的是,是什么让方法参数通过逆变转换。

对不起,很长的帖子,也许我理解错了。

编辑:

根据下面的一些对话,我了解例如使用委托层可以清楚地显示逆变性。考虑以下示例

当然这是非法的,因为有人可以将任何 Animal 传递给 someAction,而 ProcessMammal 期望任何是 Mammal 或更具体(小于 Mammal)的东西。这就是为什么 someAction 只能是 Action 或更具体的 (Action)

然而,这在中间引入了一层代表,为了实现逆变投影,是否必须在中间有一个代表?如果我们将 Process 定义为一个接口,我们会将参数参数声明为逆变类型,只是因为我们不希望有人能够做我上面展示的委托?

0 投票
2 回答
1470 浏览

generics - .net 4 泛型问题

我有以下类结构:

这给了我在 C# 4.0 中的以下编译错误。类型“Test.Y”不能用作泛型类型或方法“Test.Z”中的类型参数“T”。没有从“Test.Y”到“Test.BInterface”的隐式引用转换。

我虽然泛型中的协方差应该使这项工作?任何帮助将不胜感激。

0 投票
3 回答
713 浏览

c# - 这是协方差问题吗?不知道是不是砖墙

我编写了管理表单的 ASP.NET 页面。它们基于以下基类。

这里有一个示例子类:

下面我在页面上有一个用户控件,我想从页面“使用”“FormData”,以便它可以读取/写入它。

然后,我有一个更“通用”的用户控件,我想在我的所有表单子类的基本接口上进行操作...... IMasterForm

但是当用户控件尝试投射 Page.FormData (试图将页面投射到IHasFormData<IMasterForm>它时告诉我该页面是IHasFormData<IFormSubclass>即使我对 IFormSubclass 说它也是 IMasterForm

无论如何,我可以从泛型子类转换为泛型超类,还是这个“协方差”和 C# 4.0 的东西?

0 投票
4 回答
19211 浏览

c# - C#方差问题:分配列表作为列表

请看以下示例(部分取自MSDN 博客):

这是协方差问题吗?未来的 C# 版本是否会支持此功能,是否有任何巧妙的解决方法(仅使用 .NET 2.0)?