通用协方差和转换为SuperType [英] Generic Covariance and Casting to SuperType

查看:48
本文介绍了通用协方差和转换为SuperType的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个面向对象问题,我认为这可以归结为通用协方差.我正在尝试构建一个用于导入不同类型记录的模块化系统...模块包含常用方法,而SalesModule包含处理特定逻辑的功能...

I have an OO problem that I think can be tied back to Generic Covariance. I am trying to build a modular system for importing different types of records... Module contains the common methods, and the SalesModule contains the functions that handle specific logic...

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);  

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

How do I declare the module such that I can call the overridden methods?

推荐答案

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

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

The error is correct. We chose "out" as the keyword that indicates covariance as a reminder to you that T can only appear in "output" positions. In the line you highlight, T appears as an input.

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

T must not be an input because... well, suppose it was allowed and see what bad things happen:

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.

您刚刚将老虎列表导入了一个只知道如何处理长颈鹿的模块中.

You just imported a list of tigers into a module that only knows how to handle giraffes.

为防止这种情况,必须将第一步设为非法.类型声明带有"out"是非法的.

To prevent this, the step that has to be made illegal is the very first one. The type declaration is illegal with "out".

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

How do I declare the module such that I can call the overridden methods?

您必须声明接口,使其遵循协方差规则.具体操作由您决定,但首先不要将任何输出"参数放在输入"位置.

You have to declare the interface so that it obeys the rules of covariance. How you do that is up to you, but start by not putting any "out" parameters into "input" positions.

这篇关于通用协方差和转换为SuperType的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆