如何将C#的AccountType类改造为基类,实现子类复用属性与方法?
改造为泛型基类实现复用
我来帮你把这个AccountType类改造成一个可复用的泛型基类,这样其他子类只需要指定对应的表名,就能继承所有通用的属性和方法,并且所有方法都会返回正确的子类类型。下面是具体的改造方案:
第一步:创建泛型抽象基类 BaseEntity<T>
我们通过泛型保证方法返回正确的子类类型,同时用抽象属性让子类指定表名。基类会包含所有通用的属性、克隆方法和数据操作逻辑,这里分两种C#版本适配:
适配C# 8.0+(支持静态抽象成员)
这个版本可以直接用静态抽象属性让子类指定表名,代码更简洁:
using System; using System.Collections.Generic; using System.Data; using System.Data.SQLite; public abstract class BaseEntity<T> where T : BaseEntity<T>, new() { // 每个子类独立的静态缓存列表(泛型静态字段按封闭类型隔离) private static List<T> _entities = new List<T>(); public static List<T> Entities => _entities; // 通用属性 private int _id = -1; public int Id { get => _id; set => _id = value; } private string _name = ""; public string Name { get => _name; set => _name = value; } // 静态抽象表名,子类必须实现 protected abstract static string TableName { get; } // 克隆方法,返回子类实例 public T Clone() { return (T)MemberwiseClone(); } // 填充单条数据为子类实例 protected static T Fill(DataRow row) { if (row == null) return null; int id = Convert.ToInt32(row["id"].ToString()); string name = row["name"].ToString(); T entity = new T(); entity._id = id; entity._name = name; return entity; } // 填充多条数据为子类列表 protected static List<T> FillAll(DataRowCollection rows) { List<T> entities = new List<T>(); foreach (DataRow row in rows) { T entity = Fill(row); if (entity != null) entities.Add(entity); } return entities; } // 获取所有数据(优先用缓存) public static List<T> GetAll() { if (_entities.Count > 0) return _entities; List<T> entities = new List<T>(); string query = $"SELECT * FROM {T.TableName} WHERE id > -1 ORDER BY name"; DataSet result = Global.Db.ExecuteQuery(query); if (result == null || result.Tables[0] == null || result.Tables[0].Rows.Count < 1) return entities; entities = FillAll(result.Tables[0].Rows); _entities = entities; return entities; } // 根据ID获取单条数据(优先缓存) public static T GetById(int id) { foreach (T entity in _entities) { if (entity.Id == id) return entity; } T entityResult = null; string query = $"SELECT * FROM {T.TableName} WHERE id = {id}"; DataSet result = Global.Db.ExecuteQuery(query); if (result != null && result.Tables[0] != null && result.Tables[0].Rows.Count > 0) { entityResult = Fill(result.Tables[0].Rows[0]); } return entityResult; } // 加载数据到缓存 public static void Load() { _entities = GetAll(); } // 保存新数据(修正了原代码的参数名错误) public void Save() { string query = $"INSERT INTO {TableName} (name) VALUES (@name)"; SQLiteCommand command = new SQLiteCommand { CommandText = query, CommandType = CommandType.Text }; command.Parameters.Add(new SQLiteParameter("@name", _name)); Global.Db.ExecuteNonQuery(command); } // 更新现有数据 public void Update() { string query = $"UPDATE {TableName} SET name = @name WHERE id = @id"; SQLiteCommand command = new SQLiteCommand { CommandText = query, CommandType = CommandType.Text }; command.Parameters.Add(new SQLiteParameter("@id", _id)); command.Parameters.Add(new SQLiteParameter("@name", _name)); Global.Db.ExecuteNonQuery(command); } }
适配旧版本C#(不支持静态抽象成员)
如果你的项目用的是C# 7.3及以下,可以通过反射获取子类的静态表名字段:
// 基类中调整表名获取逻辑,以GetAll方法为例: public static List<T> GetAll() { if (_entities.Count > 0) return _entities; // 通过反射获取子类的静态tableName字段 var tableNameField = typeof(T).GetField("tableName", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); string tableName = tableNameField?.GetValue(null) as string ?? string.Empty; List<T> entities = new List<T>(); string query = $"SELECT * FROM {tableName} WHERE id > -1 ORDER BY name"; DataSet result = Global.Db.ExecuteQuery(query); if (result == null || result.Tables[0] == null || result.Tables[0].Rows.Count < 1) return entities; entities = FillAll(result.Tables[0].Rows); _entities = entities; return entities; }
第二步:子类的实现
子类只需要继承基类,指定对应的表名即可,无需编写其他重复代码:
C# 8.0+子类示例
public class AccountType : BaseEntity<AccountType> { protected override static string TableName => "accountTypes"; } // 另一个子类示例 public class UserType : BaseEntity<UserType> { protected override static string TableName => "userTypes"; }
旧版本C#子类示例
public class AccountType : BaseEntity<AccountType> { private static string tableName = "accountTypes"; } // 另一个子类示例 public class UserType : BaseEntity<UserType> { private static string tableName = "userTypes"; }
关键改造点说明
- 泛型约束:
where T : BaseEntity<T>, new()确保T是继承自BaseEntity<T>的子类,且有无参构造函数,让基类可以创建子类实例。 - 静态缓存隔离:泛型的静态字段
_entities会为每个子类创建独立缓存,不同子类的缓存不会互相干扰。 - 表名解耦:通过静态抽象属性(或静态字段+反射)让子类指定自己的数据库表名,基类无需关心具体表名。
- 类型安全:所有方法(如
GetAll、Clone)都返回T类型,调用时直接得到子类实例,无需强制转换。 - 错误修正:修复了原
Save方法中参数名错误(@currencyPair改为@name)。
这样改造后,任何需要类似功能的子类只需要继承BaseEntity<T>并指定表名,就能拥有所有通用的属性和数据操作方法,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

