How can I solve the "cannot implicitly convert error [type] to [interface]" problem when an interface has multiple common parameters?

I have the following interfaces:

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.
{
}

      

It is intended to be used IQueryHandlers

, which will take in IQuery<TResult>

, which defines a query that returns an object of type TResult

. The method then IQueryHandler

Handle

returns TResult

.

I have an interface implemented in a class 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
    }
}

      

where SomeData

is the data object, and GetDataById

-IQuery<SomeData>

However, when I try to instantiate a specific instance:

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

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

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

      

I am getting compiler error:

There is no way to implicitly convert the type DataQueryHandlers

to IQueryHandler<IQuery<SomeData>, SomeData>

. Explicit conversion exists (are you missing a role?)

I'm sure this is a covariant / contravariant problem, but I can't see where the mismatch is. Is there a problem with my inline modifiers? Is this what I am trying to do wrong in some way? I missed some obvious fish hair scenario "here?

+3


source to share


1 answer


You must change your derived class to a generic class so that it can do this. Change it like this:

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
    }
}

      



You can find more details about Generic Classes on MSDN

+2


source







All Articles