c# - C# - 如何使以下类成为基类,以便子类可以具有相同的属性、方法?
问题描述
我创建了以下类,它适用于特定的数据库表。如何使此类成为基类,以便其他类可以具有相同的属性和方法,但返回正确的类型,而我唯一要做的就是分配正确的 tableName?
在此先感谢,我希望我的问题很清楚。
这是课程:
public class AccountType
{
private static string tableName = "accountTypes";
private int id = -1;
public int Id
{
get
{
return id;
}
set
{
id = value;
}
}
private string name = "";
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
private static List<AccountType> accountTypes = new List<AccountType> ();
public static List<AccountType> AccountTypes
{
get
{
return accountTypes;
}
}
public AccountType ()
{
}
public AccountType Clone ()
{
AccountType o = (AccountType)this.MemberwiseClone ();
return o;
}
public static AccountType Fill (DataRow row)
{
int id = Convert.ToInt32 (row["id"].ToString ());
string name = row["name"].ToString ();
AccountType o = new AccountType ();
o.id = id;
o.name = name;
return o;
}
public static List<AccountType> FillAll (DataRowCollection rows)
{
List<AccountType> objs = new List<AccountType> ();
foreach (DataRow row in rows)
{
AccountType o = Fill (row);
if (o != null)
objs.Add (o);
}
return objs;
}
public static List<AccountType> GetAll ()
{
if (AccountType.accountTypes.Count > 0)
return AccountType.accountTypes;
List<AccountType> objs = new List<AccountType> ();
string query = "SELECT * \r\n" +
"FROM " + AccountType.tableName + " \r\n" +
"WHERE id > -1 \r\n" +
"ORDER BY name";
DataSet result = Global.Db.ExecuteQuery (query);
if (
(result == null)
|| (result.Tables[0] == null)
|| (result.Tables[0].Rows.Count < 1)
)
{
return objs;
}
objs = FillAll (result.Tables[0].Rows);
return objs;
}
public static AccountType GetById (int id)
{
foreach (AccountType at in AccountType.accountTypes)
{
if (at.id == id)
return at;
}
AccountType o = null;
string query = "SELECT * \r\n" +
"FROM " + AccountType.tableName + " \r\n" +
"WHERE id = " + id + " \r\n";
DataSet result = Global.Db.ExecuteQuery (query);
if (
(result == null)
|| (result.Tables[0] == null)
|| (result.Tables[0].Rows.Count < 1)
)
{
return o;
}
o = Fill (result.Tables[0].Rows[0]);
return o;
}
public static void Load ()
{
AccountType.accountTypes = AccountType.GetAll ();
}
public void Save ()
{
string tn = AccountType.tableName;
string query = "INSERT INTO " + tn + " (name) " +
"VALUES ( @name)";
SQLiteCommand command = new SQLiteCommand ();
command.CommandText = query;
command.CommandType = CommandType.Text;
command.Parameters.Add (new SQLiteParameter("@currencyPair", this.name));
Common.Global.Db.ExecuteNonQuery (command);
}
public void Update ()
{
string query = "UPDATE " + AccountType.tableName + " \r\n" +
"SET name = @name \r\n" +
"WHERE id = @id";
SQLiteCommand command = new SQLiteCommand ();
command.CommandText = query;
command.CommandType = CommandType.Text;
command.Parameters.Add (new SQLiteParameter("@id", this.id));
command.Parameters.Add (new SQLiteParameter("@name", this.name));
Common.Global.Db.ExecuteNonQuery (command);
}
}
解决方案
我 80% 确定我理解你的问题,所以希望这个答案能有所帮助。我认为奇怪重复的模板模式可能会有所帮助
这个想法是你这样做(我刚刚实现了随机位,希望能让你了解它可以为你做什么)
public abstract class BaseClass<T> where T : BaseClass<T>
{
public string Id {get; set;}
public string OtherProperty {get; set;}
public T WorkWithTAndReturn(T instanceOfASubClass)
{
//you can access base properties like
var theId = T.Id;
T.OtherProperty = "Look what I can do";
return T
}
public T Clone()
{
var newT = DoCloneStuff(instanceToClone);//do clone stuff here
return newT;
}
public static T Clone(T instanceToClone)
{
return (T)instanceToClone.MemberwiseClone();
}
}
注意:“BaseClass”是抽象的,因为您不想实例化它的实例。因为 T 必须是BaseClass<T>
你实例化子类的子类,所以你不要做这个新的 BaseClass 因为那是不必要的和奇怪的。使其抽象还允许您让实现者在需要时提供一些功能
那么你创建一个派生自的类BaseClass<T>
public class MySubClass : BaseClass<MyClass>
{
//put what ever implementation you want in here
}
它可以被使用
var mySubClass = new MySubClass();
SubClass clone = mySubClass.Clone();
SubClass otherClone = SubClass.Clone(mySubClass);
编辑:更多信息
public static T Fill(DataRow row)
{
int id = Convert.ToInt32(row["id"].ToString());
string name = row["name"].ToString();
T o = new T();
o.id = id;
o.name = name;
return o;
}
public static List<T> FillAll(DataRowCollection rows)
{
List<T> objs = new List<T>();
foreach (DataRow row in rows)
{
T o = Fill(row);
if (o != null)
objs.Add(o);
}
return objs;
}
此模式解决了您在使用静态函数时遇到的一些问题。但是,静态字段或属性只能在实现它们的类上访问。它们不是遗传的。即使 B 类继承了 A 类,A 类上的静态字符串道具也不属于 B 类。
我认为这种模式将为您指明正确的方向,但您需要重新考虑您的模式
编辑2:好的,这是我绕过静态表名字段的这个路障的想法
public abstract class TableDesciptor
{
public abstract string TableName { get; }
}
public class AccountType<T,U>
where T : AccountType<T,U>, new()
where U : TableDesciptor, new()
{
private static string tableName = new U().TableName;
public static List<T> AccountTypes
{
get
{
return accountTypes;
}
}
public int Id { get; set; }
public string Name { get; set; }
private static List<T> accountTypes = new List<T>();
public AccountType()
{
}
public T Clone()
{
T o = (T)this.MemberwiseClone();
return o;
}
public static T Fill(DataRow row)
{
int id = Convert.ToInt32(row["id"].ToString());
string name = row["name"].ToString();
T o = new T();
o.Id = id;
o.Name = name;
return o;
}
public static List<T> FillAll(DataRowCollection rows)
{
List<T> objs = new List<T>();
foreach (DataRow row in rows)
{
T o = Fill(row);
if (o != null)
objs.Add(o);
}
return objs;
}
public static List<T> GetAll()
{
if (accountTypes.Count > 0)
return accountTypes;
List<T> objs = new List<T>();
string query = "SELECT * \r\n" +
"FROM " + AccountType<T,U>.tableName + " \r\n" +
"WHERE id > -1 \r\n" +
"ORDER BY name";
DataSet result = Global.Db.ExecuteQuery(query);
if (
(result == null)
|| (result.Tables[0] == null)
|| (result.Tables[0].Rows.Count < 1)
)
{
return objs;
}
objs = FillAll(result.Tables[0].Rows);
return objs;
}
public static T GetById(int id)
{
foreach (T at in accountTypes)
{
if (at.Id== id)
return at;
}
T o = null;
string query = "SELECT * \r\n" +
"FROM " + AccountType<T,U>.tableName + " \r\n" +
"WHERE id = " + id + " \r\n";
DataSet result = Global.Db.ExecuteQuery(query);
if (
(result == null)
|| (result.Tables[0] == null)
|| (result.Tables[0].Rows.Count < 1)
)
{
return o;
}
o = Fill(result.Tables[0].Rows[0]);
return o;
}
public static void Load()
{
accountTypes = GetAll();
}
public void Save()
{
string tn = AccountType<T,U>.tableName;
string query = "INSERT INTO " + tn + " (name) " +
"VALUES ( @name)";
SQLiteCommand command = new SQLiteCommand();
command.CommandText = query;
command.CommandType = CommandType.Text;
command.Parameters.Add(new SQLiteParameter("@currencyPair", this.Name));
Common.Global.Db.ExecuteNonQuery(command);
}
public void Update()
{
string query = "UPDATE " + AccountType<T,U>.tableName + " \r\n" +
"SET name = @name \r\n" +
"WHERE id = @id";
SQLiteCommand command = new SQLiteCommand();
command.CommandText = query;
command.CommandType = CommandType.Text;
command.Parameters.Add(new SQLiteParameter("@id", this.Id));
command.Parameters.Add(new SQLiteParameter("@name", this.Name));
Common.Global.Db.ExecuteNonQuery(command);
}
}
推荐阅读
- python - 如何让python接受来自多行的输入?
- angular - 两个声明的 Angular 组件部分
- postgresql - 当应用程序可能尝试为独立但同时的进程创建临时表时,使用临时表是否安全?
- python - Google Dataflow python中的API版本BigQuery
- ruby-on-rails - 从 ActionController::UnpermittedParameters 救援
- jquery - jQuery 使用 Array 和 if/else if 根据另一个单元格的值设置表格单元格的值
- ios - DidSelectRowAtIndextPath 给了我错误的细节
- android - 适用于 Android 的 rxJava2 中的可观察 zip
- python - 如何根据从另一个表中给出的 id 获取列的值
- javascript - 精简反应过滤功能