我正在处理一个让我头疼的问题。我一直在阅读一些关于C#协方差和逆变问题的帖子,但似乎任何东西都解决了这个问题。
public abstract class BaseImporter<TEntity> : IImporter<TEntity> where TEntity : class
{
//don't pay attention to this method
public TEntity SomeMethodWhichUsesTheGenericType();
//this is the important one
protected abstract IBaseReader<IFileData> GetReader(Stream file, params object[] args);
}
public interface IImporter<out T> where T : class
{
//don't pay attention to this method
T SomeMethodWhichUsesTheGenericType();
}
public interface IBaseReader<out T> where T : IFileData
{
T GetFileData(Stream stream);
bool CanHandleStream(Stream stream, params object[] args);
}
public interface IFileData
{
}
看看我创建了一个 BaseImporter 抽象类,它暴露了一个方法 GetReader(),它将 IBaseReader 返回到某个 IFileData 即可。如果您查看IBaseReader的声明,它会指定与协方差概念相关的“ out ”关键字。
在其他程序集中,我已经声明了一些使用这些类的类。
public class JETFileData : IFileData
{
List<string> Data { get; set; }
}
public class ExcelFileReader : BaseReader<JETFileData>
{
public override bool CanHandleStream(Stream stream, params object[] args)
{
return true;
}
public override JETFileData GetFileData(Stream stream)
{
return new JetFileData() { Data = new List<string>() };
}
}
看看 JETFileData IFileData , ExcelFileReader 是一个传递Stream的读者返回< strong> JETFileData
然后我有一个来自 BaseImporter 的具体导入器。 e.g:
public class US_ETDocumentImporter : BaseImporter<US_ETDocument>
{
public List<IBaseReader<JETFileData>> Readers { get; set; }
public US_ETDocumentImporter()
{
this.Readers = new List<IBaseReader<JETFileData>>()
{
new ExcelFileReader()
};
}
//HERE IS WHERE I GOT THE ERROR!!!
protected override IBaseReader<JETFileData> GetReader(Stream file, params object[] args)
{
//decide which reader is able to be used to process this file
return this.Readers.Single(r => r.CanHandleStream(file, args));
}
}
所以,错误说:
'Importers.US_ETDocumentImporter.GetReader(System.IO.Stream, params object[])': return type must be 'Core.IBaseReader<Core.IFileData>' to match overridden member 'Core.BaseImporter<Documents.US_ETDocument>.GetReader(System.IO.Stream, params object[])'
正如我所说,我认为错误与协方差有关,但我并不完全确定。似乎编译器没有得到 JETFileData 是 IFileData 我猜。 我做错了什么?
答案 0 :(得分:1)
我认为这与协方差无关,而问题是您正试图在覆盖方法中更改返回类型。
将BaseImporter
更改为另一种通用类型,并将其约束为IFileData
public abstract class BaseImporter<TEntity, TFileData> : IImporter<TEntity>
where TEntity : class
where TFileData: IFileData
{
//don't pay attention to this method
public TEntity SomeMethodWhichUsesTEntity()
{
return null;
}
// changed IFileData to TFileData
protected abstract IBaseReader<TFileData> GetReader(Stream file, params object[] args);
}
然后,当你在US_ETDocumentImporter
中覆盖它时,你会得到你想要的东西:
public class US_ETDocumentImporter : BaseImporter<US_ETDocument,JETFileData>
{
public List<IBaseReader<JETFileData>> Readers { get; set; }
public US_ETDocumentImporter()
{
this.Readers = new List<IBaseReader<JETFileData>>()
{
new ExcelFileReader()
};
}
//HERE IS WHERE I GOT THE ERROR!!!
protected override IBaseReader<JETFileData> GetReader(Stream file, params object[] args)
{
//decide which reader is able to be used to process this file
return this.Readers.Single(r => r.CanHandleStream(file, args));
}
}