通用协方差和转换为 SuperType

2024-03-30

我有一个面向对象的问题,我认为它可以与通用协方差联系起来。我正在尝试构建一个模块化系统来导入不同类型的记录...模块包含常用方法,SalesModule 包含处理特定逻辑的函数...

public interface IImportable { ... void BuildSqlDataRecord(); ...  }
public class Sales : IImportable { ... }
public interface IModule<out T> where T : IImportable
{
    void Import(IEnumerable<T> list);  // Error Occurs here...
    IEnumerable<T> LoadFromTextFile(TextReader sr);
}
public abstract class Module<T> : IModule<T> where T : IImportable
{ 
    public void Import(IEnumerable<T> list) { ... T.BuildSqlDataRecord(); ... } 
    public IEnumerable<T> LoadFromTextFile(TextReader sr) { ... }
}
public class SalesModule : Module<Sales>
{
    public override void BuildSqlDataRecord() { ... }; 
}

在另一个函数中:

//Module<IImportable> module = null;
IModule<IImportable> module = null;
if(file.Name == "SALES")
    module = new SalesModule();
else
    module = new InventoryModule();

var list = module.LoadFromTextFile(sr);
module.Import(list);  

如何声明模块以便可以调用重写的方法?


public interface IModule<out T> where T : IImportable
{
    void Import(IEnumerable<T> list);  // Error Occurs here...
    IEnumerable<T> LoadFromTextFile(TextReader sr);
}

错误是正确的。我们选择“out”作为表示协方差的关键字,以提醒您 T 只能出现在“输出”位置。在您突出显示的行中,T 显示为输入。

T 一定不能是输入,因为......好吧,假设它被允许,看看会发生什么不好的事情:

IModule<Giraffe> gm = GetMeAModuleOfGiraffes();
IModule<Animal> am = gm; // Legal because of covariance.
IEnumerable<Tiger> tigers = GetMeASequenceOfTigers();
IEnumerable<Animal> animals = tigers; // Legal because of covariance.
am.Import(animals); // Uh oh.

您刚刚将老虎列表导入到只知道如何处理长颈鹿的模块中。

为了防止这种情况发生,必须将第一步定为非法。带“out”的类型声明是非法的。

如何声明模块以便可以调用重写的方法?

您必须声明接口,以便它遵守协变规则。如何做到这一点取决于您,但首先不要将任何“输出”参数放入“输入”位置。

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

通用协方差和转换为 SuperType 的相关文章

  • CLR 2.0 与 4.0 性能比较?

    如果在 CLR 4 0 下运行 为 CLR 2 0 编译的 NET 程序会运行得更快吗 应用程序配置
  • 如何在多线程C++ 17程序中交换两个指针?

    我有两个指针 pA 和 pB 它们指向两个大的哈希映射对象 当pB指向的哈希图完全更新后 我想交换pB和pA 在C 17中 如何快速且线程安全地交换它们 原子 我是 c 17 的新手 2个指针的原子无等待交换可以通过以下方式实现 inclu
  • GetType() 在 Type 实例上返回什么?

    我在一些调试过程中遇到了这段代码 private bool HasBaseType Type type out Type baseType Type originalType type GetType baseType GetBaseTyp
  • 如何填充 ToolStripComboBox?

    我发现它很难将数据绑定到ToolStripComboBox 好像没有这个ValueMember and DisplayMember特性 怎么绑定呢 访问toolstripcombobox中包装的组合框并访问其ValueMember Disp
  • 如何使用 Castle Windsor 将对象注入到 WCF IErrorHandler 实现中?

    我正在使用 WCF 开发一组服务 该应用程序正在使用 Castle Windsor 进行依赖注入 我添加了一个IErrorHandler通过属性添加到服务的实现 到目前为止一切正常 这IErrorHandler对象 一个名为FaultHan
  • 函数参数的默认参数是否被视为该参数的初始值设定项?

    假设我有这样的函数声明 static const int R 0 static const int I 0 void f const int r R void g int i I 根据 dcl fct default 1 如果在参数声明中指
  • 从同一个类中的另一个构造函数调用构造函数

    我有一个带有两个构造函数的类 C 这是代码片段 public class FooBar public FooBar string s constructor 1 some functionality public FooBar int i
  • 从客户端访问 DomainService 中的自定义对象

    我正在使用域服务从 Silverlight 客户端的数据库中获取数据 在DomainService1 cs中 我添加了以下内容 EnableClientAccess public class Product public int produ
  • 告诉 Nancy 将枚举序列化为字符串

    Nancy 默认情况下在生成 JSON 响应时将枚举序列化为整数 我需要将枚举序列化为字符串 有一种方法可以通过创建来自定义 Nancy 的 JSON 序列化JavaScript 原始转换器 https github com NancyFx
  • 如何在 C 中安全地声明 16 位字符串文字?

    我知道已经有一个标准方法 前缀为L wchar t test literal L Test 问题是wchar t不保证是16位 但是对于我的项目 我需要16位wchar t 我还想避免通过的要求 fshort wchar 那么 C 不是 C
  • C++ int 前面加 0 会改变整个值

    我有一个非常奇怪的问题 如果我像这样声明一个 int int time 0110 然后将其显示到控制台返回的值为72 但是当我删除前面的 0 时int time 110 然后控制台显示110正如预期的那样 我想知道两件事 首先 为什么它在
  • 保护 APK 中的字符串

    我正在使用 Xamarin 的 Mono for Android 开发一个 Android 应用程序 我目前正在努力使用 Google Play API 添加应用内购买功能 为此 我需要从我的应用程序内向 Google 发送公共许可证密钥
  • 高效列出目录中的所有子目录

    请参阅迄今为止所采取的建议的编辑 我正在尝试使用 WinAPI 和 C 列出给定目录中的所有目录 文件夹 现在我的算法又慢又低效 使用 FindFirstFileEx 打开我正在搜索的文件夹 然后我查看目录中的每个文件 使用 FindNex
  • 检测到严重错误 c0000374 - C++ dll 将已分配内存的指针返回到 C#

    我有一个 c dll 它为我的主 c 应用程序提供一些功能 在这里 我尝试读取一个文件 将其加载到内存 然后返回一些信息 例如加载数据的指针和内存块的计数到 c Dll 成功将文件读取到内存 但在返回主应用程序时 程序由于堆损坏而崩溃 检测
  • 在屏幕上获取字符

    我浏览了 NCurses 函数列表 似乎找不到返回已打印在屏幕上的字符的函数 每个字符单元格中存储的字符是否有可访问的值 如果没有的话Windows终端有类似的功能吗 我想用它来替换屏幕上某个值的所有字符 例如 所有a s 具有不同的特征
  • 堆栈是向上增长还是向下增长?

    我在 C 中有这段代码 int q 10 int s 5 int a 3 printf Address of a d n int a printf Address of a 1 d n int a 1 printf Address of a
  • 使用 omp_set_num_threads() 将线程数设置为 2,但 omp_get_num_threads() 返回 1

    我有以下使用 OpenMP 的 C C 代码 int nProcessors omp get max threads if argv 4 NULL printf argv 4 s n argv 4 nProcessors atoi argv
  • 如何在richtextbox中使用多颜色[重复]

    这个问题在这里已经有答案了 我使用 C windows 窗体 并且有 richtextbox 我想将一些文本设置为红色 一些设置为绿色 一些设置为黑色 怎么办呢 附图片 System Windows Forms RichTextBox有一个
  • 使用 C 在 OS X 中获取其他进程的 argv

    我想获得其他进程的argv 例如ps 我使用的是在 Intel 或 PowerPC 上运行的 Mac OS X 10 4 11 首先 我阅读了 ps 和 man kvm 的代码 然后编写了一些 C 代码 include
  • GCC 的“-Wl,option”和“-Xlinker option”语法之间有区别吗?

    我一直在查看一些配置文件 并且看到它们都被使用 尽管在不同的体系结构上 如果您在 Linux 机器上使用 GCC 将选项传递给链接器的两种语法之间有区别吗 据我所知 阅读 GCC 手册时 他们的解释几乎相同 From man gcc Xli

随机推荐

  • Xcode 7 Git 找不到远程存储库

    我可以在 Xcode 6 X 上毫无问题地推送和拉取此存储库 但它在 Xcode 7 上不起作用 设置与 Xcode 6 X 相同 我尝试输入用户名和密码只是为了确认 但似乎没有任何意义 我使用了正确的 SSH 密钥作为身份验证 但首选项显
  • 如何通过指针处理矩阵中的子矩阵?

    我有一个大小为 n 的矩阵 举个例子 我的递归函数对位于矩阵边界的元素进行处理 现在我想在内方矩阵上调用它 递归调用 这是我的递归函数的原型 void rotate int mat size t n 我知道二维数组是数组中的数组 我知道 m
  • Springfox 类参数已弃用

    在Springfox 3 0中 springfox documentation service Parameter已弃用 是否有提供参数及其构建器的更新方法 以及如何提供其default value 首先 使用RequestParamete
  • 使用 function.php 的单一产品的 Woocommerce 元数据

    我正在努力通过我的functions php 正确过滤元数据 I can get this to work if I edit the meta php in my child theme with no problem short sto
  • 将数据从VSS迁移到SVN

    如何将我的数据从 VSS 迁移到 SubVersion 这取决于您是否想随身携带 VSS 元数据 如果是 请看一下电源管理员 http www poweradmin com sourcecode vssmigrate aspx or Vss
  • 版本号大于 1.18.10 的正则表达式 [重复]

    这个问题在这里已经有答案了 我需要验证应用程序的版本号是否大于 1 18 10 在这种情况下 正则表达式应该是什么样子 不要为此使用正则表达式 使用split and tuple比较 def is recent version versio
  • 将点击事件与 Twitter Bootstrap 结合使用

    我正在使用 twitter bootstrap 开发一个可以在多个设备上呈现的 Web 应用程序 现在我想处理 点击 事件 所以我的问题是 我可以使用 jquery 1 7 2 处理 tap 事件而不使用 jquery Mobile 吗 如
  • minikube docker-env 是什么意思?

    在 Kubernetes 中minikube 教程 https kubernetes io docs tutorials hello minikube create your node js application有这个命令可以使用 Min
  • 如何在批处理脚本中找到应用程序的完整路径

    如何在批处理脚本中找到应用程序 XYZ 如果已安装 的完整路径 澄清 应用程序不在 PATH 中 我所拥有的就是它的名称 在本例中为 ISTool exe 我想得到C 程序 ISTool ISTool exe 您可以在路径 或其他类似路径的
  • 在类本身内部创建类实例是如何工作的?

    是什么使得在类本身内部创建类的实例成为可能 public class My Class My Class new class new My Class 我知道这是可能的 并且自己也做到了 但我仍然无法让自己相信这不是 谁先有鸡还是先有蛋 之
  • 中使用自定义模板名称

    目前我有这段代码 它为每个用户节点调用 用户 模板
  • 如何在没有 Root 设备的情况下使用自己的 Android 服务进行屏幕截图?

    我进行了很多搜索并找到了两个库 1 https code google com p android screenshot library https code google com p android screenshot library
  • 如何使用elasticsearch正确处理多词同义词扩展?

    我有以下同义词扩展 suco gt suco refresco bebida de soja 我想要的是以这种方式标记搜索 搜索 suco de laranja 将被标记为 suco laranja refresco bebida de s
  • 在 ggplot 或lattice 中利用 Surv 对象

    有人知道如何利用 ggplot 或lattice 进行生存分析吗 制作网格或类似面的生存图会很好 所以最后我尝试了一下 找到了卡普兰 迈耶图的解决方案 对于将列表元素放入数据框中的混乱代码 我深表歉意 但我无法找到其他方法 注意 它仅适用于
  • Jenkins Git 插件包含不工作的区域

    我无法使用 Git 插件在 Jenkins 中使用 包含区域 功能 我希望仅在 他的 目录发生更改时才构建作业 示例 项目 mytool 仅应在以下内容发生更改时构建GIT ROOT tools mytool 我在包含的区域字段中尝试了几种
  • 删除默认标题栏

    如何删除 Android 应用程序中默认的顶部标题栏 灰色的你好 Android 吧 删除标题栏非常简单 只需将 android theme 属性添加到 AndroidManifest xml 中即可
  • ICollection 的简单现有实现

    有没有简单的实现ICollection
  • AngularJS 指令中的 locals 代表什么

    AFAIK 这没有记录 但我在角度源中发现locals指令示例中的属性 angular module transclude directive pane function return restrict E transclude true
  • 如何使用已安装的斜纹登录网站?

    我刚刚安装成功TWILL https web archive org web 20180904160747 http twill idyll org 80 在 StackOverflow 一位非常支持的成员的帮助下在我的计算机上 你可以查看
  • 通用协方差和转换为 SuperType

    我有一个面向对象的问题 我认为它可以与通用协方差联系起来 我正在尝试构建一个模块化系统来导入不同类型的记录 模块包含常用方法 SalesModule 包含处理特定逻辑的函数 public interface IImportable void