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
- 一个通用接口
,带有一个方法,该方法接收TQuery(对IQueryHandler
有一个约束)并返回一个TQuery:IQuery
TReturnType
- 具体处理程序,实现接收具体查询并返回TQuery的
IQueryHandler
- 一种
,它有一个接收查询并返回结果的方法。具体类将从DI容器中查找正确的处理程序QueryDispatcher
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);
}
}