Как сделать следующий класс базовым классом, чтобы дочерние классы могли иметь одинаковые свойства, методы? - PullRequest
0 голосов
/ 16 мая 2018

Я создал следующий класс, который работает с определенной таблицей базы данных.Как я могу сделать этот класс базовым классом, чтобы другие классы могли иметь те же свойства и методы, но возвращать правильный тип, и единственное, что мне нужно сделать, - это присвоить правильное имя таблицы?

Заранее спасибоНадеюсь, мой вопрос ясен.

Вот класс:

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);
    }
}

1 Ответ

0 голосов
/ 17 мая 2018

Я уверен на 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;
    }

Этот шаблон решает некоторые проблемы, возникающие у вас со статическими функциями. Однако статические поля или свойства доступны только в том классе, в котором они реализованы. Они не наследуются. Статическая строка в классе A не принадлежит классу B, даже если класс B наследуется от класса A.

Я думаю, что этот паттерн укажет вам правильное направление, но вам нужно будет немного переосмыслить ваш паттерн


Редактировать 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...