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

  • 表示查询对象
  • 的通用接口(interface)IQuery<T>
  • 一个具体的查询类具有一些getter和setters(实现IQuery<T>)
  • 具有单个方法的通用接口(interface)IQueryHandler<TReturnType, TQuery>,该方法接收TQuery(对TQuery: IQuery<TReturnType>进行约束)并返回TReturnType
  • 实现IQueryHandler的具体处理程序,接收具体的ConcreteQuery并返回TQuery
  • 一个QueryDispatcher,它具有接收查询并返回结果的单个方法。具体的类将从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)+具体的查询处理程序
    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());
    

    最佳答案

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

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

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

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

    09-27 03:39