我遇到了创建查询类的通用列表的问题。这些查询类派生自具有自引用类型约束的基本抽象泛型类。
精简基类和派生类是:
public abstract class AbstractQuery<TQuery, TResult>
where TQuery : AbstractQuery<TQuery, TResult>
{
public IEnumerable<TResult> Query ()
{
return new List<TResult>();
}
}
public class FirstQuery : AbstractQuery<FirstQuery, object> { }
public class SecondQuery : AbstractQuery<SecondQuery, object> { }
应用程序代码想要创建这些查询的列表并在每个查询上执行Query方法,例如:
var queryList = new List<AbstractQuery<AbstractQuery, object>>
{
new FirstQuery(),
new SecondQuery()
};
foreach ( var query in queryList )
{
query.Query();
}
此部分未构建,因为List类型当然无效。所以我的问题是我可以使用哪种类型的List来正确使用此代码?
作为旁注,我们通过添加带有AbstractQuery实现的Query方法签名的IQuery接口,但仍然希望查看初始方式是否可行来解决另一种方式。是的,在实际代码中有一个自引用约束的原因 - 它需要一些反射代码。
答案 0 :(得分:5)
您尝试将AbstractQuery<TQuery, TResult>
视为与TQuery
相关的协变。对于泛型参数,类不能是协变的。只允许接口(甚至在某些情况下,仅在某些情况下)使其通用参数变量(协变或逆变)。这就是为什么它可以使用一个接口而不是一个抽象类。