You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现动态泛型抽象类遇CS0310错误:SqlQueryDynamicGetCbmClients需非抽象且带无参构造

搞定CS0310错误:泛型类型参数的构造函数约束问题

嘿,这个CS0310错误我之前也踩过坑,咱们先把问题拆明白,再针对你的场景给出解决方案~

先搞懂错误到底说啥

Severity Code Description Project File Line Suppression State Error CS0310 'SqlQueryDynamicGetCbmClients'必须是具有公共无参数构造函数的非抽象类型,才能在泛型类型或方法中用作参数'TSelf'。

简单说,你定义的泛型抽象类(或者调用的泛型方法)对TSelf这个泛型参数加了new()约束——意思是这个类型必须能通过new 类型()的方式实例化。但你的SqlQueryDynamicGetCbmClients不满足这个要求:要么它是个抽象类(抽象类没法直接new),要么它没有公开的无参数构造函数(比如你只写了带参数的构造,编译器不会自动给你生成无参的)。

针对你的场景的修复思路

你的目标是简化动态泛型抽象类,适配“子类的TParams不同但Result相同”的场景,那我们可以从三个方向调整:

思路1:删掉没必要的new()约束

如果你的泛型基类根本不需要直接实例化TSelf,那这个约束完全可以去掉。比如你原来的基类可能是这么写的:

public abstract class BaseDynamicQuery<TSelf, TParams, TResult> 
    where TSelf : BaseDynamicQuery<TSelf, TParams, TResult>, new()
{
    // ... 你的基类逻辑
}

直接把new()约束删掉就行:

public abstract class BaseDynamicQuery<TSelf, TParams, TResult> 
    where TSelf : BaseDynamicQuery<TSelf, TParams, TResult>
{
    // ... 调整后的逻辑
}

思路2:让SqlQueryDynamicGetCbmClients满足约束

如果你的基类逻辑必须依赖new()约束(比如要在基类里创建子类实例),那就要修改你的子类:

  • 如果它是抽象类,改成非抽象类(只要符合你的设计初衷)
  • 给它加一个公开的无参数构造函数。比如:
public class SqlQueryDynamicGetCbmClients : BaseDynamicQuery<SqlQueryDynamicGetCbmClients, ClientParams, CommonResult>
{
    // 必须加这个公开无参构造
    public SqlQueryDynamicGetCbmClients() { }

    // 你原来的带参数构造可以保留
    public SqlQueryDynamicGetCbmClients(string connectionString)
    {
        // ... 你的初始化逻辑
    }

    // ... 其他类逻辑
}

思路3:重构泛型设计,彻底避开这个约束

既然你的场景是“多个子类共享同一个Result类型,只是TParams不同”,那完全可以重构基类,去掉TSelf这个参数,让基类固定Result类型,子类只需要指定TParams:

// 基类:固定Result类型,子类只传TParams就行
public abstract class BaseDynamicQuery<TParams, TResult>
{
    public abstract TResult Execute(TParams parameters);
}

// 你的子类:Params是ClientParams,Result是CommonResult
public class SqlQueryDynamicGetCbmClients : BaseDynamicQuery<ClientParams, CommonResult>
{
    public override CommonResult Execute(ClientParams parameters)
    {
        // ... 你的业务逻辑
    }
}

// 其他同Result的子类,只需要换TParams
public class AnotherCbmQuery : BaseDynamicQuery<OtherParams, CommonResult>
{
    public override CommonResult Execute(OtherParams parameters)
    {
        // ... 对应的业务逻辑
    }
}

这种设计更贴合你的需求,还避免了TSelf带来的构造函数约束问题,代码也更简洁。

最后总结一下

先检查你的泛型基类是不是真的需要new()约束——不需要就直接删;需要的话就调整子类满足条件。如果能重构泛型设计去掉TSelf,那是最省心的,完全避开这个坑。

内容的提问来源于stack exchange,提问作者Eryk Hubert Siejka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:53:38