使用接口和通用约束键入推断

时间:2014-02-22 17:54:50

标签: c# generics type-inference

我正在构建一个通用的查询调度程序。这个想法如下:

  • 表示查询对象的通用接口IQuery<T>
  • 具体的查询类包含一些getter和setter(实现IQuery<T>
  • 通用接口IQueryHandler<TReturnType, TQuery>,其中包含一个接收TQuery(约束TQuery: IQuery<TReturnType>)并返回TReturnType
  • 的方法
  • 实现IQueryHandler的具体处理程序,它接收具体的ConcreteQuery并返回一个TQuery
  • 一个QueryDispatcher,它有一个接收Query并返回结果的方法。具体类将从DI容器中查找正确的处理程序。

问题是当我在Fetch上调用QueryDispatcher方法时,我没有得到类型推断。有什么我可以做的类型推断或这只是c#的限制?

理论上它应该知道类型参数是什么,因为它接收TQuery的参数,该参数具有IQuery<TReturnType的约束。

这是代码:

class ConcreteClass    // This is the class of which I want to query objects
{
}

查询界面+具体查询类

interface IQuery<T>
{
}

public class ConcreteQuery : IQuery<ConcreteClass>
{
}

QueryHandler接口+具体的查询处理程序

interface IQueryHandler<TReturnType, TQuery> where TQuery : IQuery<TReturnType>
{
    TReturnType Fetch(TQuery query);
}

class ConcreteQueryHandler : IQueryHandler<ConcreteClass, ConcreteQuery>
{
    ConcreteClass Fetch(ConcreteQuery query)
    {
    }
}

QueryDispatcher(使用DI容器来解析正确的处理程序)

class QueryDispatcher
{
    TReturnType Fetch<TReturnType, TQuery>(TQuery query) 
        where TQuery : IQuery<TReturnType>
    {
        return myDIcontainer.Get<IQueryHandler<T, TQuery>>().Fetch(query);
    }
}

现在当我像这样使用QueryDispatcher时,我收到一个错误:

var queryDispatcher = new QueryDispatcher();
var c = queryDispatcher.Fetch(new ConcreteQuery());

当我提供类型参数时,一切正常:

var c = queryDispatcher.Fetch<ConcreteClass, ConcreteQuery>(new ConcreteQuery());

1 个答案:

答案 0 :(得分:0)

你想要的是两级类型推断,编译器不会这样做。

您可能想要重新考虑您的查询调度程序。可以将其视为需要IQuery<TReturnType>并返回TReturnType的内容。

尝试将查询调度程序更改为:

class QueryDispatcher
{
    public TReturnType Fetch<TReturnType>(IQuery<TReturnType> query) 
    {
        return myDIcontainer
            .Get<IQueryHandler<TReturnType, IQuery<TReturnType>>>()
            .Fetch(query);
    }
}