C#抽象类&接口 项目实操选型清单(开发直接对照)

C#抽象类&接口 项目实操选型清单(开发直接对照)

一、快速判定5条规则(遇到场景直接选)

✅ 选【抽象类 abstract】满足任意一条

  1. 多个子类共用字段/成员变量(Id、Name、公共缓存、连接对象等)
  2. 多个子类有大量重复业务代码,只想部分方法由子类重写
  3. 需要通过构造函数统一初始化子类公共数据
  4. 业务是 is-a 从属关系:XX是一种XX(货车→车辆、MySQLDao→BaseDao)
  5. 需要使用 private/protected 封装内部私有逻辑

✅ 选【接口 interface】满足任意一条

  1. 类需要具备多个互不相关的功能(多能力组合,C#单继承做不到)
  2. 只定义行为规范,没有公共属性、没有共享数据(契约定义)
  3. 无关业务类需要统一行为标准(文件、网络、数据库都要释放资源→IDisposable)
  4. 分层架构、依赖注入、单元测试Mock(Service层依赖IXXXService)
  5. 插件化、可替换实现类(随时切换Sql实现、Redis实现)

二、项目常用组合方案(工业级标准写法:接口+抽象类)

接口:定义对外契约;抽象类:实现接口+封装公共代码;实体类:继承抽象类

//1.接口:对外约束规范
public interface IUserRepository
{
    User GetById(int id);
    bool Add(User user);
}
//2.抽象类:实现接口,封装公共逻辑
public abstract class BaseUserRepo : IUserRepository
{
    protected DbContext _db; //公共字段,所有子类复用
    protected BaseUserRepo(DbContext db) => _db = db;
    //公共通用实现
    public virtual bool Add(User user)
    {
        _db.Add(user);
        return _db.SaveChanges()>0;
    }
    //抽象方法由不同数据库实现
    public abstract User GetById(int id);
}
//3.具体实现
public class SqlUserRepo : BaseUserRepo
{
    public SqlUserRepo(DbContext db):base(db){}
    public override User GetById(int id)
    {
        return _db.Users.Find(id);
    }
}

适用场景:仓储层、服务层通用架构

三、避坑黑名单(这些场景严禁乱用)

禁止用抽象类的场景

  1. 只为给类加一个附加功能(如可排序、可导出)→改用接口
  2. 后期需要更换多种实现、插件扩展→优先接口

原因:抽象类单继承,一旦继承占用,无法再继承别的基类

禁止全用接口的场景

  1. 十几个实现类都有一模一样的属性(CreateTime、Creator)→抽抽象类存字段
  2. 大量重复的工具逻辑,每个实现类重复写→抽象类封装公共方法

原因:接口无字段,所有实现类重复代码,维护成本暴增

四、版本兼容选型(C#版本区分)

  1. .NET Framework / C#7.3及以下
    接口尽量少新增方法,新增必改全部实现类;通用公共逻辑一律抽象类。
  2. .NET Core3.1+ / C#8.0+
    接口可用默认实现新增方法,不需要改动实现类,部分通用逻辑可下沉到接口。

五、业务场景对照表

业务场景 选型方案
各种数据库Dao(Mysql/Oracle/SqlServer) 接口IRepository + 抽象BaseRepository + 具体实现类
工具能力:导出Excel、打印、排序 单独接口 IExport、IPrint、ISort
不同类型支付(微信/支付宝) IPay接口 + BasePay抽象类封装公共签名逻辑
框架规范:释放资源、比较大小 纯接口(IDisposable、IComparable)

六、一句话总结口诀

契约解耦用接口,共有状态抽象类;
多能组合上接口,从属继承抽象类;
大型项目最优解,接口定规范,抽象做复用。

posted @ 2026-06-04 07:25  人生就是修炼  阅读(12)  评论(0)    收藏  举报