contravariance 相关问题

在编程语言的类型系统中,协方差和逆变是指从较窄到较宽的类型的排序以及它们在某些情况下的可互换性或等价性(例如参数,泛型和返回类型)

为什么协方差不适用于泛型方法

假设我有接口和类: 公共接口 ITree {} 公共类树:ITree {} 由于 IEnumerable 是协变的,因此下面的代码行编译成功: IE可枚举 假设我有接口和类: public interface ITree {} public class Tree : ITree {} 由于IEnumerable<T>是协变,所以下面的代码行编译成功: IEnumerable<ITree> trees = new List<Tree>(); 但是当我将它放入泛型方法中时: public void Do<T>() where T : ITree { IEnumerable<ITree> trees = new List<T>(); } 我从编译器中得到编译错误: 错误1无法将类型“System.Collections.Generic.List”隐式转换为“System.Collections.Generic.IEnumerable”。存在显式转换(是否缺少转换?) D:\lab\Lab.General\Lab.General\Program.cs 83 40 Lab.General 为什么协方差在这种情况下不起作用? 这是因为方差仅适用于引用类型(类、接口和委托)。添加一个类约束,它就可以正常编译了: public static void Do<T>() where T : class, ITree 我只是想添加更多示例: 您可以调用 MakeDesignWhereTIsReference 并将 VehicleStruct 传递为 T。但问题是: 引用类型支持协变和逆变,但值类型不支持它们。来自MS 文档 所以我们还需要限制T为引用类型;这可以借助 class 关键字来完成,该关键字添加了我们需要的限制。 public static class TestCovariance { public static void MakeDesignWhereTIsReference<T>() where T : class, IVehicle // pay attention to class restriction { ICollection<IDesign<IVehicle>> list = new List<IDesign<IVehicle>>(); var design = new Design<T>(); list.Add(design); } public static void MakeDesignWhereTIsStruct<T>() where T : struct, IVehicle //This method will throw a cast exception { ICollection<IDesign<IVehicle>> list = new List<IDesign<IVehicle>>(); var design = new Design<T>(); list.Add((IDesign<IVehicle>)design); } } public struct VehicleStruct : IVehicle { } TestCovariance.MakeDesignWhereTIsReference<Ship>(); TestCovariance.MakeDesignWhereTIsStruct<VehicleStruct>();

回答 2 投票 0

为什么采用不兼容参数类型的函数类型的联合被认为等同于采用“从不”的函数?

type fnType = ((x: number) => void) | ((x: 字符串) => void); const fn = (innerFn: fnType) => { 内部Fn(“字符串”); } 如果我执行上述操作,打字稿会显示“Argument o...

回答 1 投票 0

正确使用 Typescript Set<T> 和交叉类型

我不明白为什么编译器会抱怨。以下是基本类型声明: 导出枚举 SvgElementType { 路径=“路径”, 圆=“圆”, } 出口类型

回答 2 投票 0

不变性、协变性和逆变性——有比喻吗?

首先我想说的是,我知道这个话题已经在 Stack Overflow 上进行了深入讨论。但我不认为给出的解释提供了有助于保留示例的强有力的故事......

回答 3 投票 0

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

昨天在一个研讨会上,演讲者(Peter Sestoft)展示了一个小型 Java 程序,有 3 个类,具有协方差和逆变的特点。当尝试使用 javac 进行编译时,类型 ch...

回答 2 投票 0

通用方差类型参数(Kotlin)

我不完全理解泛型中的方差是如何工作的。在下面的代码中,类如下 Any -> Mammals -> Cats。 Any 是超类型,有一个参数从副本中调用

回答 1 投票 0

如何在打字稿中为带参数但不带任何参数的函数类型指定类型保护?

函数类型对于参数来说是逆变的,对于返回类型来说是协变的。在这种情况下,如何指定带有扩展容器类型的参数的通用函数类型而不使用任何类型? 类型

回答 1 投票 0

为什么 C# 4.0 的协变/逆变仅限于参数化接口和委托类型?

这是 CLR 的限制还是与现有代码存在兼容性问题? 这是否与 C# 4.0 中委托组合的混乱方差有关? 编辑: 是否可以...

回答 3 投票 0

为什么C#不允许参数类型逆变?

C#支持返回类型协变,但为什么不支持参数类型逆变。 想象一下这个例子: 抽象类动物 { 公共抽象无效PlayWith(玩具玩具); } 班级

回答 1 投票 0

.NET 4.0 通用不变式、协变式、逆变式

这是我面临的场景: 公共抽象类记录{} 公共抽象类 TableRecord : 记录 { } 公共抽象类 LookupTableRecord : TableRecord { } 公章密封...

回答 2 投票 0

泛型兼容性

我知道这通常可以追溯到方差,但我不确定如何解决下面显示的问题。 我想要一个通用传感器列表,并将特定传感器类型添加到列表中,但是这

回答 1 投票 0

具有通用处理程序和查询的 Mediatr

我正在使用 Mediatr 开发 ASP.NET Core 2.2 Web API 应用程序。 我有一个看起来像的处理程序 - 公共类 MyQueryHandler : IRequestHanlder, IQueryable<...

回答 6 投票 0

Rust 协变和逆变

我很好奇 Rust 是否像 C# 一样支持协变和逆变, 例如,在 C# 中,有委托 Func: 委托 TResult Func(T arg); 对象 F1(字符串 s) { 返回空值;...

回答 0 投票 0

如何在一个类中有一个参量以及一个函数来变换它?

我有一个非常简单的类:case class Foo[+T](t: T) 现在我想添加一个参数来将T转化为Int。由于特殊原因,我不想使用类型类、隐式或任何基于继承的 ...

回答 1 投票 0

通用类型中的C#协方差

对于这个简单的例子,我无法绕过C#协方差,下面是我如何定义我的模型: 接口IResponse { } 接口ICommand 其中 TResponse : IResponse { } 类 ...

回答 1 投票 0


回答 3 投票 103

我的变通量通用参数的解决方法是否必要?

我从一个简单的通用接口开始:interface IFooContext {TObject Value {get; }字符串DoSomething (Expression > ...

回答 1 投票 2

将接口传递给另一个接口方法

我需要在OOP中实现事件监听器模型。现在我有了EventInterface和ListenerInterface。但是我想将事件传递给侦听器,例如:interface ListenerInterface {public function ...

回答 1 投票 0

有没有一种方法可以键入TypeScript方法装饰器,以限制它可以装饰的方法类型?

我想编写一个TypeScript方法装饰器,该装饰器只能应用于具有某种类型的第一个参数的方法。这是我正在传递请求的代码库中的常见模式...

回答 2 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.