【问题标题】:How do I solve the "cannot implicitly convert [type] to [interface]" error when the interface has multiple generic parameters?当接口有多个泛型参数时,如何解决“无法将[type]隐式转换为[interface]”错误?
【发布时间】:2017-05-11 15:47:55
【问题描述】:

我有以下接口:

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&lt;TResult&gt;,该IQuery&lt;TResult&gt; 定义了一个返回TResult 类型对象的查询。然后IQueryHandler 的Handle 方法返回一个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 是一个数据实体,GetDataById 是一个IQuery&lt;SomeData&gt;

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

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&lt;IQuery&lt;SomeData&gt;, SomeData&gt;。显式转换 存在(您是否缺少演员表?)

我确定这是一个与协变/逆变相关的问题,但我看不到不匹配的位置。我的输入/输出通用修饰符有问题吗?我正在尝试做的事情在某种程度上是根本不正确的吗?我在这里错过了一些明显的“hair on a fish”场景吗?

【问题讨论】:

  • 尝试将 DataQueryHandlers : IQueryHandler 更改为 DataQueryHandlers : IQueryHandler where TResult : class where TQuery : IQuery
  • @S.Petrosov 您应该将此作为答案而不是评论发布。用一句话解释原因,我认为这解决了问题。

标签: c# generics


【解决方案1】:

您应该将派生类更改为通用类才能做到这一点。 改成这样:

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

【讨论】:

  • 嗯,我明白了。但这要求 DataQueryHandlers 现在处理 all TQuery 对象,而不仅仅是我想要指定的特定对象。我怀疑这是我的整体架构的问题。
猜你喜欢
  • 1970-01-01
  • 2020-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-20
  • 2010-10-25
相关资源
最近更新 更多