基类的抽象方法

本文关键字:抽象方法 基类 | 更新日期: 2023-09-27 18:35:45

我有一个名为DAL_Base的基类,用于执行大部分SQL提升的大型项目。

DAL_Base具有用于SELECT语句、GetRecords()方法和virtual FillData(IDataRecord)的字段。

public class DAL_Base<T> where T : IDisposable, new() {
  private string connStr;
  public DAL_Base() {
    connStr = ConfigurationManager.ConnectionStrings["CompanyDatabaseConnStr"].ConnectionString;
  }
  internal string SP_GET { get; set; }
  internal SqlConnection m_openConn {
    get {
      var obj = new SqlConnection(connStr);
      obj.Open();
      return obj;
    }
  }
  internal virtual T FillDataRecord(IDataRecord record) {
    return new T();
  }
  internal TList<T> Get() {
    if (String.IsNullOrEmpty(SP_GET)) {
      throw new NotSupportedException(string.Format("Get Procedure does not exist for {0}.", typeof(T)));
    }
    var list = new TList<T>();
    using (var cmd = new SqlCommand(SP_GET, m_openConn)) {
      cmd.CommandType = cmd.GetCommandTextType();
      using (var r = cmd.ExecuteReader()) {
        while (r.Read()) {
          list.Add(FillDataRecord(r));
        }
      }
      cmd.Connection.Close();
    }
    return list;
  }
}

还有更多,但这应该足以举个例子。

TList只是一个List<T>类:

internal class TList<T> : List<T> {
  public TList() { }
}

当我的一个类继承自它时,我希望它能够覆盖基类的FillDataRecord(IDataRecord)

例如,EmployeeDB 继承 **DAL_BASE

当我调用EmployeeDB.GetEmployeeList()时,它使用DAL_BASE来拉取记录:

public class EmployeeDB : DAL_Base<Employee> {
  private static EmployeeDB one;
  static EmployeeDB() {
    one = new EmployeeDB() {
      SP_GET = "getEmployeeList",
    };
  }
  private EmployeeDB() { }
  internal override Employee FillDataRecord(IDataRecord record) {
    var item = base.FillDataRecord(record);
    item.Emp_Login = record.Str("Emp_Login");
    item.Emp_Name = record.Str("Emp_Name");
    item.Emp_Email = record.Str("Emp_Email");
    item.Emp_Phone = record.Str("Emp_Phone");
    item.Emp_Role = record.Str("Emp_Role");
    return item;
  }
  public static EmployeeList GetEmployeeList() {
    var list = new EmployeeList();
    list.AddRange(one.Get());
    return list;
  }
}

在上面的代码中,当GetEmployeeList()调用DAL_Base方法Get()时,只调用DAL_Base::FillDataRecord(IDataRecord)。

我真的需要调用 EmployeeDB::FillDataRecord(IDataRecord

),但我无法使 DAL_Base::FillDataRecord(IDataRecord) 抽象。

解决这个问题的方法是什么?

我现在所知道的就是创建一个EventHandler,这是我刚刚想到的,所以我将朝着这个方向努力。

如果有人知道更好的路线,请插话!

基类的抽象方法

一种解决方案是通过构造函数将 Derived.FillDataRecord 的委托传递给基类。

public class DAL_Base<T> where T : IDisposable, new() {
  private string connStr;
  public DAL_Base() {
    connStr = ConfigurationManager.ConnectionStrings["CompanyDatabaseConnStr"].ConnectionString;
  }
    private Func<IDataRecord, T> _fillFunc;
    public DAL_Base(Func<IDataRecord, T> fillFunc) : this() {
            _fillFunc = fillFunc;
    }
        // ... 
    internal TList<T> Get() {
    if (String.IsNullOrEmpty(SP_GET)) {
      throw new NotSupportedException(string.Format("Get Procedure does not exist for {0}.", typeof(T)));
    }
    var list = new TList<T>();
    using (var cmd = new SqlCommand(SP_GET, m_openConn)) {
      cmd.CommandType = cmd.GetCommandTextType();
      using (var r = cmd.ExecuteReader()) {
        while (r.Read()) {
          list.Add(_fullFunc(r));
}

在派生类中:

public class EmployeeDB : DAL_Base<Employee> {
    public EmployeeDB() : base(r => FillDataRecord(r)) { }
  private Employee FillDataRecord(IDataRecord record) {
    var item = base.FillDataRecord(record);
    item.Emp_Login = record.Str("Emp_Login");
    item.Emp_Name = record.Str("Emp_Name");
    item.Emp_Email = record.Str("Emp_Email");
    item.Emp_Phone = record.Str("Emp_Phone");
    item.Emp_Role = record.Str("Emp_Role");
    return item;
  }
}