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

在哪些场景下适合使用C#的new修饰符实现方法隐藏?

C# new修饰符合理使用示例:Fluent构建器模式的类型适配

核心场景说明

在实现链式调用的Fluent接口(最常见的是各类构建器)时,我们通常希望子类的同名方法返回更具体的子类类型,让调用者可以直接调用子类独有的方法,不需要额外的强制类型转换。这种场景下使用new修饰符是完全合理的,且优势远大于override。

代码实现示例

基类通用构建器

public class DbCommandBuilder
{
    protected int _timeout;
    protected string _sql;

    public DbCommandBuilder WithSql(string sql)
    {
        _sql = sql;
        return this;
    }

    public virtual DbCommandBuilder WithTimeout(int seconds)
    {
        _timeout = seconds;
        return this;
    }

    // 其他通用方法,比如Build生成最终的DbCommand
    public virtual DbCommand Build() => new DbCommand(_sql, _timeout);
}

子类特化构建器

我们针对SqlServer做特化的构建器,新增独有的加密配置方法。如果用override实现WithTimeout,返回值只能是基类DbCommandBuilder,调用完WithTimeout后就无法直接调用子类独有的WithEncryption方法,必须强转,非常影响使用体验。
此时用new修饰符重新定义WithTimeout即可完美解决问题:

public class SqlServerCommandBuilder : DbCommandBuilder
{
    private bool _enableEncryption;

    // 用new修饰符,返回子类类型,内部复用基类逻辑
    public new SqlServerCommandBuilder WithTimeout(int seconds)
    {
        base.WithTimeout(seconds);
        return this;
    }

    // 子类独有的配置方法
    public SqlServerCommandBuilder WithEncryption(bool enable)
    {
        _enableEncryption = enable;
        return this;
    }

    // 重写Build方法生成SqlServer特有的Command
    public override DbCommand Build()
    {
        var command = base.Build();
        command.EnableEncryption = _enableEncryption;
        return command;
    }
}

使用效果对比

使用new修饰符的调用代码

// 链式调用完全流畅,不需要任何强转
var sqlServerCommand = new SqlServerCommandBuilder()
    .WithSql("SELECT Id,Name FROM Users")
    .WithTimeout(30) // 此处返回SqlServerCommandBuilder类型
    .WithEncryption(true) // 可直接调用子类独有方法
    .Build();

如果用override的调用代码

var sqlServerCommand = new SqlServerCommandBuilder()
    .WithSql("SELECT Id,Name FROM Users")
    .WithTimeout(30) // 此处返回DbCommandBuilder类型
    // 必须强制转换才能调用子类方法,既麻烦又容易抛出转换异常
    ((SqlServerCommandBuilder)this).WithEncryption(true)
    .Build();

符合要求的验证

  • 不是演示用的简单示例:该实现是生产环境中Fluent构建器的通用方案,EF Core、ASP.NET Core等官方类库的构建器逻辑中都有类似实现。
  • 相比override的优势明确:彻底解决了链式调用时的类型丢失问题,不需要额外强转,代码更简洁,出错概率更低。
  • 不是“没法重写才用new”的被动选择:基类的WithTimeout本身是可重写的virtual方法,但override受语法限制不能修改返回值类型,new是主动选择的更优实现方案。
  • 无混淆风险:子类new的WithTimeout逻辑完全复用基类实现,除返回值类型更具体外,行为和基类完全一致,不管用基类变量还是子类变量调用,最终执行效果没有差异,符合调用者预期。

内容的提问来源于stack exchange,提问作者User1291

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:48:03