gpt4 book ai didi

c# - 通用协变和转换为 SuperType

转载 作者:行者123 更新时间:2023-11-30 13:23:51 24 4
gpt4 key购买 nike

我有一个 OO 问题,我认为它可以追溯到通用协方差。我正在尝试构建一个用于导入不同类型记录的模块化系统...模块包含常用方法,而 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 只能出现在“output”位置。在您突出显示的行中,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”的类型声明是非法的。

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

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

关于c# - 通用协变和转换为 SuperType,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8378777/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com