返回List <derivedclass>

时间:2015-07-24 14:07:35

标签: c# c#-4.0 covariance

我正在处理一个让我头疼的问题。我一直在阅读一些关于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[])' 

图片也可能有用: enter image description here

正如我所说,我认为错误与协方差有关,但我并不完全确定。似乎编译器没有得到 JETFileData IFileData 我猜。  我做错了什么?

1 个答案:

答案 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));
    }
}