使用通用接口约束时的协变/逆变难题

2023-12-31

    public interface IShape{}

    public class Rectangle : IShape{}

    public class Base{}

    public class Derived : Base{}

    public interface IFoo<out T, in U>
        where T : IShape
        where U : Base
    {
        T Convert(U myType);
    }

    public class MyFoo : IFoo<Rectangle, Derived>
    {
        public Rectangle Convert(Derived myType)
        {
            throw new NotImplementedException();
        }
    }    

    class Program
    {
        static void Main(string[] args)
        {
            IFoo<IShape, Base> hmm = new MyFoo();
        }
    }

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

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

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


你的 IFoo 接口在这种用法中似乎是错误的,它应该是:

public interface IFoo<out T, **out** U>

With U外出。请记住,一个out泛型类型参数意味着它可以“向外”变化。也就是说,您可以隐式地将类型扩展为更宽的类型。In不过,这意味着您可以隐式地将类型“向内”缩小为更具体的类型。当然,这些只是粗略的类比。

所以在分配的情况下hmm,您正在隐式地尝试扩大接口泛型类型参数U from Derived to Base,但接口声明它正在缩小(in):

IFoo<IShape, Base> hmm = new MyFoo();

所以它不能进行隐式转换。如果您确实希望能够隐式扩展此接口,则第二个类型参数应该是out代替in.

更新:在您发表评论后,我发现最大的困境是您希望它既可以输入又可以输出,这实际上是不可能的,因为它是逆变输入,所以您不能将接口协变分配给IFoo<IShape, Base>, 很遗憾。

您要么需要围绕无法分配给的事实进行编码IFoo<IShape,Base>或者你可以做的是将 Foo 创建为:

public class MyFoo : IFoo<Rectangle, Base>

然后投射到Rectangle内部实施。最主要的是,同一类型参数不能同时具有协变和逆变。

这有道理吗?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用通用接口约束时的协变/逆变难题 的相关文章

  • 使用 mono/nunit-console/4 在 Mac OS X 控制台上运行测试

    我安装了 Max OS X 10 11 1 上面装有 Xamarin 我编写了简单的测试类 只是为了测试在 Mac OS X 和 Ubuntu 上运行 Nunit 测试 该类实际上有一个返回字符串的方法 using System names
  • QCombobox 向下箭头图像

    如何更改Qcombobox向下箭头图像 现在我正在使用这个 QSS 代码 但这不起作用 我无法删除向下箭头边框 QComboBox border 0px QComboBox down arrow border 0px background
  • 为什么在创建矩阵类时使用向量不好?

    对于我的矩阵类 我做了 template
  • 平滑滚动.net 表单

    您好 我正在 net 中使用表单 并且在运行时动态添加大量链接标签 我将这些链接标签添加到面板并将该面板添加到 winform 当链接标签的数量增加时 表单会显示一个自动滚动条 垂直 现在 当我使用自动滚动向下滚动时 表单在滚动时不会更新其
  • 与 Qt 项目的静态链接

    我有一个在 Visual Studio 2010 Professional 中构建的 Qt 项目 但是 当我运行它 在调试或发布模式下 时 它会要求一些 Qt dll 如果我提供 dll 并将它们放入 System32 中 它就可以工作 但
  • 指向特征矩阵的指针数组

    我在代码中使用 Eigen 的 MatrixXd 矩阵 在某个时刻我需要一个 3D 矩阵 由于 Eigen 没有三维矩阵类型 因为它仅针对线性代数进行了优化 因此我创建了一个 MatrixXd 类型的指针数组 Eigen MatrixXd
  • ASP.Net Core 内容配置附件/内联

    我正在从 WebAPI 控制器返回一个文件 Content Disposition 标头值自动设置为 附件 例如 处置 附件 文件名 30956 pdf 文件名 UTF 8 30956 pdf 当它设置为附件时 浏览器将要求保存文件而不是打
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • 如何在 QTabWidget Qt 中展开选项卡

    我有一个QTabWidget像这个 但我想展开选项卡以 填充 整个小部件宽度 如下所示 我怎样才能做到这一点 我在用Qt 5 3 2 and Qt 创建者 3 2 1 Update 我尝试使用setExpanding功能 ui gt myT
  • 为什么 set_symmetry_difference 无法与比较器一起使用?

    Example program include
  • Visual Studio Code:如何配置 includePath 以获得更好的 IntelliSense 结果

    我是使用 Visual Studio Code 的完全初学者 我不知道我在做什么 我已经四处搜索 也许还不够 但我找不到像我这样的人如何配置的简单解释c cpp properties json每当我单击带有绿色波浪线下划线的行旁边的黄色灯泡
  • 给出 5 个参数,但在终端中只得到 3 个参数

    我想将一个文件传递给一个c 程序 如果我在 IDE 中执行此操作 test string string lt test txt return argc 5 但在终端上我刚刚得到argc 3 看来 这是因为 什么是 lt 意思是 我正在使用
  • 无法在内存位置找到异常源:cudaError_enum

    我正在尝试确定 Microsoft C 异常的来源 test fft exe 中 0x770ab9bc 处的第一次机会异常 Microsoft C 异常 内存位置 0x016cf234 处的 cudaError enum 我的构建环境是 I
  • 运行选定的代码生成器时出错:“未将对象引用设置到对象的实例。”错误?

    我已经尝试了所有解决方案 例如修复 VS 2013 但没有用 当您通过右键单击控制器文件夹来创建控制器并添加控制器时 然后右键单击新创建的控制器的操作并选择添加视图 当我尝试创建视图时 就会发生这种情况 它不是一个新项目 而是一个现有项目
  • 如何分析组合的 python 和 c 代码

    我有一个由多个 python 脚本组成的应用程序 其中一些脚本正在调用 C 代码 该应用程序现在的运行速度比以前慢得多 因此我想对其进行分析以查看问题所在 是否有工具 软件包或只是一种分析此类应用程序的方法 有一个工具可以将 python
  • 在 EnvDTE 中调试时捕获 VS 局部变量

    是否可以使用 EnvDTE 进行 vsix Visual Studio 扩展来捕获本地和调试窗口使用的调试数据 或者可以通过其他方法吗 我想创建一个自定义的本地窗口 我们可以修改它以根据需要显示一些较重的内容 而无需为高级用户牺牲原始的本地
  • 新任务中使用的依赖注入服务

    我在需要时使用依赖项注入来访问我的服务 但我现在想要创建一个并发任务 但这会由于依赖项注入对象及其生命周期而导致问题 我读过这篇文章 标题 防止多线程 Link http mehdi me ambient dbcontext in ef6
  • 了解使用 Windows 本机 WPF 客户端进行 ADFS 登录

    我已经阅读了大量有关 ADFS 与 NodeJS Angular 或其他前端 Web 框架集成以及一般流程如何工作的文献 并通过 Auth0 Angular 起始代码构建了概念证明 但我不明白如何这可以与本机 WPF Windows 应用程
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • 从 JavaScript 中的 OnClientClick 事件中阻止 C# 中的 asp:Button OnClick 事件?

    我有一个asp Button在我的网页上 它调用 JavaScript 函数和代码隐藏方法 后者进行调用以导航到另一个页面 在 JavaScript 函数中 我正在检查条件 如果不满足这个条件 我想中止导航 以便OnClick方法未被调用

随机推荐

  • lub(T1,...Tn) 是什么意思?

    以下引用来自 JLS 14 20 http docs oracle com javase specs jls se8 html jls 14 html jls 14 20 异常参数的声明类型 将其类型表示为 与替代方案 D1 的结合D2 D
  • OpenCV 霍​​夫圆

    我使用 Xcode 和 c 我已经从以下位置复制了 HoughCircles 代码OpenCV 文档 http opencv willowgarage com documentation cpp feature detection html
  • 在 SageMath 中运行时使用 Dask 会抛出 ImportError

    最近 我一直在尝试使用 Dask 并行化一些 Sage 运行 OSX 11 2 3 的 MacBook Pro 上的 Sage 9 4 代码 我遇到的问题是 虽然我可以在 Sage 中运行 Dask 但每当我包含任何非 纯 python 代
  • 我们可以将事件侦听器添加到“Vega-Lite”规范吗?

    我是 Vega 和 Vega Lite 的新手 我正在使用 Vega Lite 创建一个简单的条形图 但我无法添加任何事件侦听器 例如 徘徊 我想将鼠标悬停在一个栏上并更改该栏的颜色 如果您正在使用Vega嵌入 https github c
  • 如何收到图库应用程序可见的每个新图像的通知?

    背景 当用户下载新图像或使用相机捕获图像时 图库应用程序将更新以显示新图像 我需要在创建每个新图像后立即收到通知 无论它是如何创建的 相机 浏览器 就像图库应用程序所示 问题 事实证明 有一个 mediaScanner Android 组件
  • Curl:传输已关闭,剩余未完成的读取数据

    我遇到了大卷曲调用的问题 I get nread 传输已关闭 剩余未完成的读取数据 并且内容已部分交付 GET stats stats breakdown track track campaign search criteria 2 per
  • 无法生成用于构建和调试的资产。 OmniSharp 服务器未运行

    在 Visual Studio VS Code 上 使用 C 进行编码 我正在尝试生成要构建和调试的资产 但收到以下错误消息 无法生成用于构建和调试的资产 OmniSharp 服务器未运行 我在跑 NET版本3 1 301 视窗8 1 Vi
  • 从小表中删除重复行

    我在 PostgreSQL 8 3 8 数据库中有一个表 该表没有键 约束 并且有多行具有完全相同的值 我想删除所有重复项并仅保留每行的 1 个副本 特别有一列 名为 key 可用于识别重复项 即每个不同的 key 应该只存在一个条目 我怎
  • 需要在ggplot2中绘制条形图(以百分位方式)

    嗨 我有一个这样的数据集 ALL Critical Error Warning Review 2016 1412 475 4 125 154 45 49 2 58 116 86 12 1 17 我想使用 ggplot2 绘制堆叠条形图 其中
  • 混合构造函数并在 Javascript 代理对象上应用陷阱

    我有一个类 我想对其应用代理 观察方法调用和构造函数调用 计算器 js class Calc constructor add a b return a b minus a b return a b module exports Calc i
  • 仅查看 Mercurial 中的目录?

    如何仅从 Mercurial 存储库中查看子目录 看来我只能查看整个存储库 你不能 请参阅此处的讨论 https www mercurial scm org wiki PartialClone https www mercurial scm
  • SparkSQL CSV 的引用不明确

    我正在尝试在 SparkSQL 2 10 中读取一堆 CSV 文件 其自定义架构部分是 Double 部分是 String 如下所示 Build the schema val schemaStringS col1 col2 val sche
  • MatPlotLib 修改自定义线性分段颜色图

    关于已接受的答复这个问题 https stackoverflow com questions 38882233 geopandas matplotlib plot custom colors 38885389 38885389 如果我想使用
  • Java 期货管道

    我正在努力优化我的Future的管理技术 假设我们有这种典型的处理场景 我运行一个查询以从数据库中获取一些记录 SELECT FROM mytable WHERE mycondition 该查询返回很多我需要处理的行 例如 while re
  • 清除 TList 或 TObjectList

    我对使用什么来存储列表中的对象有点困惑 到目前为止我已经使用过TList并释放循环中的每个项目 然后我发现TObjectList自动执行此操作Free 然后我从文档中看到了这个TList Clear Call Clear清空 Items 数
  • C Unix 管道示例

    尝试实现一个shell 主要是管道 我已经编写了这个测试用例 我希望将 ls 简单地通过管道传输到 wc 它肯定不会按预期工作 它将 ls 打印到终端 然后打印内存耗尽 我非常不知道如何解决这个问题并让它发挥作用 find path 在我的
  • 从多个 SQL 文件恢复 SQL

    我有一个包含 400 多个 sql 文件的数据库备份 foreach表有一个单独的sql文件 是否可以将所有这些文件一起导入数据库 如果可以的话你能告诉我该怎么做吗 备份也是一个 gzip 压缩的 tar 文件 有没有办法从压缩文件中恢复
  • 动态xpath表达式

    美好的一天 同事们 请告诉我如何进行动态 xpath 解析 例如 而不是写 domXPath gt query id article id 18 gt 写类似的东西 domXPath gt query id article id 因为在我的
  • 现代和旧的编译器是用什么编写的?

    作为编译器 而不是解释器 只需要翻译输入而不运行它 其本身的性能应该不会像解释器那样有问题 因此 您不会用 Ruby 或 PHP 编写解释器 因为它太慢了 但是 编译器呢 如果您用脚本语言编写一个编译器 甚至可能具有快速开发的特点 您可能会
  • 使用通用接口约束时的协变/逆变难题

    public interface IShape public class Rectangle IShape public class Base public class Derived Base public interface IFoo