当接口有多个通用参数时,如何解决“无法隐式转换[type]到[interface]”错误?

时间:2017-05-11 15:47:56

标签: c# generics

我有以下界面:

public interface IQueryHandler<in TQuery, out TResult> where TResult : class 
                                                where TQuery : IQuery<TResult>
{
    TResult Handle(TQuery query);
}

public interface IQuery<TResult> // Doesn't require anything special, just used to guarantee that IQueryHandlers get the right parameters.
{
}

它旨在由IQueryHandlers使用,它将接收IQuery<TResult>,该TResult定义返回类型为IQueryHandler的对象的查询。 Handle的{​​{1}}方法会返回TResult

我在DataQueryHandlers类上实现了接口:

public class DataQueryHandlers : IQueryHandler<GetDataById, SomeData>
{
    private IDataSource source;

    public DataQueryHandlers(IDataSource source)
    {
        this.source = source
    }

    public SomeData Handle(GetDataById query)
    {
        // Get the data here and return SomeData object
    }
}

其中SomeData是数据实体,而GetDataByIdIQuery<SomeData>

但是,当我尝试实例化特定实例时:

private IQueryHandler<IQuery<SomeData>, SomeData> dataQueryHandlers;
private IDataSource source;

source = new DataSource(); // some data provider

dataQueryHandlers = new DataQueryHandlers(datasource); // This line won't compile

我收到编译错误:

  

无法将DataQueryHandlers类型隐式转换为   IQueryHandler<IQuery<SomeData>, SomeData>。显式转换   存在(你是否错过演员表?)

我确定这是一个协变/逆变相关的问题,但我没看到不匹配的地方。我的输入/输出通用修饰符有问题吗?从某种意义上说,我试图从根本上做错吗?我在这里错过了一些明显的“hair on a fish”情景吗?

1 个答案:

答案 0 :(得分:2)

您应该将派生类更改为通用类以便能够执行此操作。 将其更改为:

public class DataQueryHandlers<in TQuery, out TResult> : IQueryHandler<TQuery, TResult> where TResult : class where TQuery : IQuery<TResult>
{
    private IDataSource source;

    public DataQueryHandlers(IDataSource source)
    {
        this.source = source
    }

    public TResult Handle(TQuery query)
    {
        // Get the data here and return TResult object
    }
}

有关通用课程的更多信息,请参阅MSDN