具有自引用约束的C#通用抽象类

3

我遇到了一个关于创建我们查询类的通用列表的问题。这些查询类都是从基础抽象泛型类派生出来的,并且具有自引用类型约束。

简化后的基础类和派生类如下:

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来使此代码正确运行?

顺便说一句,我们通过添加一个具有Query方法签名的IQuery接口,并由AbstractQuery实现来解决了这个问题,但仍然希望看到最初的方式是否可行。是的,实际代码中存在自引用约束的原因 - 它需要一些反射代码。

1个回答

6
您正在尝试将AbstractQuery<TQuery, TResult>视为相对于TQuery是协变的。但是,类不能相对于泛型参数是协变的。只有接口(而且仅在某些情况下)允许使其泛型参数具有变异性(可以是协变或逆变)。这就是为什么如果使用接口而不是抽象类,则可以正常工作的原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接