基类的抽象方法
本文关键字:抽象方法 基类 | 更新日期: 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)。
),但我无法使 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;
}
}