C# 具有接口和泛型约束的类型推断

C# 具有接口和泛型约束的类型推断,c#,generics,type-inference,C#,Generics,Type Inference,我正在构建一个通用查询调度器。其思路如下: 表示查询对象的通用接口IQuery 一个具体的查询类有一些getter和setter(实现IQuery) 一个通用接口IQueryHandler,带有一个方法,该方法接收TQuery(对TQuery:IQuery有一个约束)并返回一个TReturnType 具体处理程序,实现接收具体查询并返回TQuery的IQueryHandler 一种QueryDispatcher,它有一个接收查询并返回结果的方法。具体类将从DI容器中查找正确的处理程序 问题是

我正在构建一个通用查询调度器。其思路如下:

  • 表示查询对象的通用接口
    IQuery
  • 一个具体的查询类有一些getter和setter(实现
    IQuery
  • 一个通用接口
    IQueryHandler
    ,带有一个方法,该方法接收TQuery(对
    TQuery:IQuery
    有一个约束)并返回一个
    TReturnType
  • 具体处理程序,实现接收具体查询并返回TQuery的
    IQueryHandler
  • 一种
    QueryDispatcher
    ,它有一个接收查询并返回结果的方法。具体类将从DI容器中查找正确的处理程序
问题是,在调用
QueryDispatcher
上的
Fetch
方法时,我没有得到类型推断。我能做些什么来得到类型推断,还是这只是c#的一个限制


理论上,它应该知道类型参数是什么,因为它接收到一个参数
TQuery
,该参数对
IQuery有一个约束,您想要的是一个两级类型推断,而编译器不会这样做

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

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

class QueryDispatcher
{
    public TReturnType Fetch<TReturnType>(IQuery<TReturnType> query) 
    {
        return myDIcontainer
            .Get<IQueryHandler<TReturnType, IQuery<TReturnType>>>()
            .Fetch(query);
    }
}
类查询Dispatcher
{
公共树类型获取(IQuery查询)
{
返回myDIcontainer
.Get()
.Fetch(查询);
}
}

不要认为你有其他选择,因为它现在无法解决TreturnTypes问题是“为什么不?”这是c#?@Kenneth的限制吗如果你将
var
更改为真实类型,它会有帮助吗?不,也尝试过,虽然这不会有什么区别。但我是对的,理论上,编译器应该能够做到这一点,但是C#编译器不够聪明,对吗?这样更改查询调度程序的问题是,我无法为不同的IQuery解决不同的查询处理程序
interface IQuery<T>
{
}

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

class ConcreteQueryHandler : IQueryHandler<ConcreteClass, ConcreteQuery>
{
    ConcreteClass Fetch(ConcreteQuery query)
    {
    }
}
class QueryDispatcher
{
    TReturnType Fetch<TReturnType, TQuery>(TQuery query) 
        where TQuery : IQuery<TReturnType>
    {
        return myDIcontainer.Get<IQueryHandler<T, TQuery>>().Fetch(query);
    }
}
var queryDispatcher = new QueryDispatcher();
var c = queryDispatcher.Fetch(new ConcreteQuery());
var c = queryDispatcher.Fetch<ConcreteClass, ConcreteQuery>(new ConcreteQuery());
class QueryDispatcher
{
    public TReturnType Fetch<TReturnType>(IQuery<TReturnType> query) 
    {
        return myDIcontainer
            .Get<IQueryHandler<TReturnType, IQuery<TReturnType>>>()
            .Fetch(query);
    }
}