Считать значение атрибута производного класса - PullRequest
1 голос
/ 22 апреля 2019

Я создаю приложение, которое будет работать с SQLite, и сейчас я хочу получить строки для создания таблиц для каждой сущности, которые должны храниться с кодом, подобным следующему:

table_creation_string1 = Book.GetTableCreationString();
table_creation_string2 = Scroll.GetTableCreationString();

, который будетПозвольте мне выполнить минимальную работу с созданием новых сущностей с использованием пользовательских атрибутов для хранения имен таблиц и имен полей.

Вот мой пример настройки:

[System.AttributeUsage(System.AttributeTargets.Class)]
public class DBItemAttribute : System.Attribute
{
    public string TableName;
    public DBItemAttribute(string table_name)
    {
        TableName = table_name;
    }
}

internal abstract class DBItem
{
    ...
}


[DBItemAttribute("book_table")]
internal class Book : DBItem
{
    ...
}

[DBItemAttribute("scroll_table")]
internal class Scroll : DBItem
{
    ...
}

Проблема, с которой я столкнулся, заключается в том, что яне может получить значение атрибута для классов Book и Scroll без создания объекта.Другими словами - используя что-то вроде этого:

string table1 = Scroll.GetTableName();
string table2 = Book.GetTableName();

с выводом следующих значений

"scroll_table"
"book_table"

Так что я ищу лучшие решения для этого или несколько хороших альтернатив.

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

UPD:код вроде

table_creation_string1 = new Book().GetTableCreationString();

работает наверняка, но мне интересно, можно ли это сделать так, как я описал выше.

Ответы [ 3 ]

2 голосов
/ 22 апреля 2019

Атрибуты - это свойства класса, поэтому вам не нужно создавать экземпляр этого класса, чтобы получить эти значения. Для этого вы можете создать отдельный вспомогательный класс:

internal static class DBHelpers
{
    public static string GetTableName<TDBItem>()
        where TDBItem : DBItem
    {
        var attribute = typeof(TDBItem).GetCustomAttribute<DBItemAttribute>();
        return attribute?.TableName;
    }
}

Так что теперь вы можете использовать его так:

var tableName1 = DBHelpers.GetTableName<DBHelpers>();
var tableName2 = DBHelpers.GetTableName<Book>();
1 голос
/ 22 апреля 2019

Метод статического класса

Просто измените internal class Book и internal class Scroll на статические, как static class Book и static class Book.Это вся цель, кто статические классы.

Определение статического класса

Статический класс - это класс, создание которого невозможно.Единственная цель этого класса - предоставить чертежи его унаследованных классов.Статический класс создается с использованием ключевого слова static в C #.Статический класс может содержать только статические члены.Вы не можете создать объект для статического класса.

Создание экземпляра и вызов метода. В противном случае вы можете создать его экземпляр и вызвать метод следующим образом: new Book().GetTableName()

0 голосов
/ 22 апреля 2019

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


    public class ClassFactory
        {
            public static Action GetTableName(string className)
            {
                switch (className)
                {
                    case "Scroll": return "Book_table";
                    case "Book": return "Book_table";
                }
            }
         }

позвоните в этот класс:


string table1 = ClassFactory.GetTableName("Scroll");
string table2 = ClassFactory.GetTableName("Book");

...