Reflection - Тип унаследованного класса из наследуемого
От: _SM_ Украина  
Дата: 23.08.05 10:08
Оценка:
Друзья, уже сломал голову. Последняя наежда на вас.

Есть класс DBEntity и его статический метод CreateTable,
есть унаследованный класс User со своими свойствами.

Нужно при вызове User.CreateTable получить коллекцию всех
свойств юзера. Как это сделать?


--------------------------------



    class User: DBEntity
    {
        
        private string m_Username = "";
        private string m_Password = "";

        public string Username        
        {
            get {return m_Username;}
            set {m_Username = value;}
        }
        
        public string Password
        {
            get {return m_Password;}
            set {m_Password = value;}
        }

        public User() {}

        public User(string Username, string Password)
        {
            m_Username = Username;
            m_Password = Password;
        }

    }

    public class DBEntity
    {
        public static bool CreateTable()
        {
        }
    }
Re: Reflection - Тип унаследованного класса из наследуемого
От: vitaly_spb Россия  
Дата: 23.08.05 10:16
Оценка:
Может так?

typeof(User).GetProperties()
...Ei incumbit probatio, qui dicit, non qui negat...
Re[2]: Reflection - Тип унаследованного класса из наследуемо
От: _SM_ Украина  
Дата: 23.08.05 10:21
Оценка:
Здравствуйте, vitaly_spb, Вы писали:

_>Может так?


_>
_>typeof(User).GetProperties()
_>



В том и дело, что DBEntity не имеет права знать, кто его наследует
Тоесть, кто бы его ни унаследовал, нужно получить список свойств наследника...
Выход, конечно, сделать метод не статическим и использовать тогда this.GetType()
(т.к. this уже содержит в себе контекст наследника). Тут задача — получить контекст
наследуемого типа из унаследованного статического метода.
Re: Reflection - Тип унаследованного класса из наследуемого
От: EM Великобритания  
Дата: 23.08.05 10:38
Оценка: 3 (1)
Здравствуйте, _SM_, Вы писали:

_SM>Друзья, уже сломал голову. Последняя наежда на вас.


_SM>Есть класс DBEntity и его статический метод CreateTable,

_SM>есть унаследованный класс User со своими свойствами.

_SM>Нужно при вызове User.CreateTable получить коллекцию всех

_SM>свойств юзера. Как это сделать?


1. Сделать метод нестатическим.
2.
foreach (PropertyDescriptor pd in System.ComponentModel.TypeDescriptor.GetProperties(this))
{
    object obj = pd.GetValue(this);
}
Опыт — это такая вещь, которая появляется сразу после того, как была нужна...
Re: Reflection - Тип унаследованного класса из наследуемого
От: V.Petrovski Беларусь  
Дата: 23.08.05 10:42
Оценка: 3 (1)
Здравствуйте, _SM_, Вы писали:

_SM>Нужно при вызове User.CreateTable получить коллекцию всех

_SM>свойств юзера. Как это сделать?

В таком виде статический метод не подойдет,
т.к. он не наследуется

Как варианты:
class DBEntity
{
    public void CreateTable()
    {
        CreateTable(GetType());
    }
    public static void CreateTable(Type type)
    {
        Console.WriteLine(type);
    }
}
<< RSDN@Home 1.1.4 stable rev. 510>>
Re: Reflection - Тип унаследованного класса из наследуемого
От: Hobot Bobot США  
Дата: 23.08.05 10:43
Оценка: 3 (1)
Здравствуйте, _SM_, Вы писали:

_SM>Есть класс DBEntity и его статический метод CreateTable,

_SM>есть унаследованный класс User со своими свойствами.

_SM>Нужно при вызове User.CreateTable получить коллекцию всех

_SM>свойств юзера. Как это сделать?


Насколько я знаю — никак. Варианты — делать вручную методы CreateTable в каждом наследнике DBEntity или передавать в метод CreateTable тип как параметр (User.CreateTable(User.GetType())).
What a piece of work is a man! how noble in reason! how infinite in faculty! in form and moving how express and admirable! in action how like an angel! in apprehension how like a god! the beauty of the world! the paragon of animals!
Re[2]: Reflection - Тип унаследованного класса из наследуемо
От: Real_Asv Россия  
Дата: 23.08.05 11:05
Оценка:
VP>В таком виде статический метод не подойдет,
VP>т.к. он не наследуется

Можно вопрос — почему статические методы не наследуются?
Вот в документации другое пишут:
Instance constructors, destructors, and static constructors are not inherited, but all other members are.
Статические конструкторы сильно отличаются от статических методов
Control yourself.
Re[2]: Reflection - Тип унаследованного класса из наследуемо
От: _SM_ Украина  
Дата: 23.08.05 11:10
Оценка:
Здравствуйте, Hobot Bobot, Вы писали:

HB>Насколько я знаю — никак. Варианты — делать вручную методы CreateTable в каждом наследнике DBEntity или передавать в метод CreateTable тип как параметр (User.CreateTable(User.GetType())).


Ну да, так и работает сейчас, не статический метод.
Сделаю хелпер-класс DBManager и туда все положу..
Спасибо за поддержку!
Re[3]: Reflection - Тип унаследованного класса из наследуемо
От: Real_Asv Россия  
Дата: 23.08.05 11:39
Оценка:
Последний штрих, теории ради.
Не получится использовать static метод, не из за того что он не наследуется, а из за того что в коде static метода нельзя использовать this.
Вот к примеру:

        internal class DBEntity
        {
            public void NSCreateTable()
            {
                                Console.WriteLine(this.GetType().Name);                
            }
            public static void CreateTable()
            {
                Console.WriteLine("Static member");
            }
        }
        internal class User : DBEntity
        {
            private string _name;
            private string _pwd;
            public User(string name,string pwd)
            {
                this._name=name;
                this._pwd=pwd;
            }
            public string Name
            {
                get{return _name;}
            }
            public string Pwd
            {
                get{return _pwd;}
            }
        }

При вызове кода

            User user=new User("n","p");
            user.NSCreateTable();

Все работает прекрасно — возвращаемый тип — User.
В static методе использование такого кода невозможно:
C# Language Specification
10.2.5 Static and instance members
A static function member (method, property, event, operator, or constructor) does not operate on a specific instance, and it is a compile-time error to refer to this in such a function member.
Control yourself.
Re[4]: Reflection - Тип унаследованного класса из наследуемо
От: _SM_ Украина  
Дата: 23.08.05 11:47
Оценка:
Здравствуйте, Real_Asv, Вы писали:

R_A>Последний штрих, теории ради.

R_A>Не получится использовать static метод, не из за того что он не наследуется, а из за того что в коде static метода нельзя использовать this.
R_A>Вот к примеру:


R_A>Все работает прекрасно — возвращаемый тип — User.

R_A>В static методе использование такого кода невозможно:
R_A>C# Language Specification
R_A>10.2.5 Static and instance members
R_A>A static function member (method, property, event, operator, or constructor) does not operate on a specific instance, and it is a compile-time error to refer to this in such a function member.


Все понятно, но речь шла не о получении ссылки на экземпляр объекта, а о получении
унаследованного типа, у которого вызывается этот статический метод.
Re[5]: Reflection - Тип унаследованного класса из наследуемо
От: Real_Asv Россия  
Дата: 23.08.05 11:58
Оценка:
_SM>Все понятно, но речь шла не о получении ссылки на экземпляр объекта, а о получении
_SM>унаследованного типа, у которого вызывается этот статический метод.

А разве есть методы которые позволят получить тип унаследованного класса в котором вызывается метод кроме использования this?
IMHO в этом контексте две формулировки которые вы привели одинаковы....
Control yourself.
Re: Reflection - Тип унаследованного класса из наследуемого
От: Аноним  
Дата: 23.08.05 13:33
Оценка:
Здравствуйте, _SM_, Вы писали:

_SM>Друзья, уже сломал голову. Последняя наежда на вас.


_SM>Есть класс DBEntity и его статический метод CreateTable,

_SM>есть унаследованный класс User со своими свойствами.

_SM>Нужно при вызове User.CreateTable получить коллекцию всех

_SM>свойств юзера. Как это сделать?


_SM>--------------------------------

_SM>



_SM>    class User: DBEntity
_SM>    {
        
_SM>        private string m_Username = "";
_SM>        private string m_Password = "";

_SM>        public string Username        
_SM>        {
_SM>            get {return m_Username;}
_SM>            set {m_Username = value;}
_SM>        }
        
_SM>        public string Password
_SM>        {
_SM>            get {return m_Password;}
_SM>            set {m_Password = value;}
_SM>        }

                public DataColumnCollection Columns
                {
                        get {...}
                        set {...}
                }


_SM>        public User() {}

_SM>        public User(string Username, string Password)
_SM>        {
_SM>            m_Username = Username;
_SM>            m_Password = Password;
_SM>        }

_SM>    }

_SM>    public class DBEntity
_SM>    {

                public abstract DataColumnCollection Fields { get; }

_SM>        public static bool CreateTable(DBEntity entity)
_SM>        {
_SM>        }
_SM>    }

_SM>


Можно переписать вот так — тогда рефлекшн вообще не понадобиться. Вместо DataColumnCollection можно использовать MyColumnClass[]. Вообще, если работаешь с большим числом сущностей в базе полезно и удобно заводить и использовать свои метаданные об этих сущностях, а не изобретать велосипед с рефлекшеном — сильно облегчает жизнь.
Re[2]: Reflection - Тип унаследованного класса из наследуемо
От: Hobot Bobot США  
Дата: 23.08.05 13:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Можно переписать вот так — тогда рефлекшн вообще не понадобиться. Вместо DataColumnCollection можно использовать MyColumnClass[]. Вообще, если работаешь с большим числом сущностей в базе полезно и удобно заводить и использовать свои метаданные об этих сущностях, а не изобретать велосипед с рефлекшеном — сильно облегчает жизнь.


И как вызывать из static-метода CreateTable instance-свойство Columns?
What a piece of work is a man! how noble in reason! how infinite in faculty! in form and moving how express and admirable! in action how like an angel! in apprehension how like a god! the beauty of the world! the paragon of animals!
Re[6]: Reflection - Тип унаследованного класса из наследуемо
От: _SM_ Украина  
Дата: 23.08.05 16:16
Оценка:
Здравствуйте, Real_Asv, Вы писали:

_SM>>Все понятно, но речь шла не о получении ссылки на экземпляр объекта, а о получении

_SM>>унаследованного типа, у которого вызывается этот статический метод.

R_A>А разве есть методы которые позволят получить тип унаследованного класса в котором вызывается метод кроме использования this?


Получение ссылки на экземпляр, позволяет получить тип.
Таких методов не знаю, поэтому и спрашивал, возможно ли
получить этот тип внутри _статического_ метода.

R_A>IMHO в этом контексте две формулировки которые вы привели одинаковы....


Тип объекта и экземпляр — разные вещи.
Re[2]: Reflection - Тип унаследованного класса из наследуемо
От: _SM_ Украина  
Дата: 23.08.05 16:19
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, _SM_, Вы писали:


_SM>>Друзья, уже сломал голову. Последняя наежда на вас.


_SM>>Есть класс DBEntity и его статический метод CreateTable,

_SM>>есть унаследованный класс User со своими свойствами.

_SM>>Нужно при вызове User.CreateTable получить коллекцию всех

_SM>>свойств юзера. Как это сделать?


_SM>>--------------------------------

_SM>>



_SM>>    class User: DBEntity
_SM>>    {
        
_SM>>        private string m_Username = "";
_SM>>        private string m_Password = "";

_SM>>        public string Username        
_SM>>        {
_SM>>            get {return m_Username;}
_SM>>            set {m_Username = value;}
_SM>>        }
        
_SM>>        public string Password
_SM>>        {
_SM>>            get {return m_Password;}
_SM>>            set {m_Password = value;}
_SM>>        }
А>
А>                public DataColumnCollection Columns
А>                {
А>                        get {...}
А>                        set {...}
А>                }
А>

_SM>>        public User() {}

_SM>>        public User(string Username, string Password)
_SM>>        {
_SM>>            m_Username = Username;
_SM>>            m_Password = Password;
_SM>>        }

_SM>>    }

_SM>>    public class DBEntity
_SM>>    {
А>
А>                public abstract DataColumnCollection Fields { get; }
А>
_SM>>        public static bool CreateTable(DBEntity entity)
_SM>>        {
_SM>>        }
_SM>>    }

_SM>>


А>Можно переписать вот так — тогда рефлекшн вообще не понадобиться. Вместо DataColumnCollection можно использовать MyColumnClass[]. Вообще, если работаешь с большим числом сущностей в базе полезно и удобно заводить и использовать свои метаданные об этих сущностях, а не изобретать велосипед с рефлекшеном — сильно облегчает жизнь.



Делаем библиотеку для продажи, а не для себя.
Свои метаданные, конечно, проще для понимания,
но зачем тогда придумали рефлекшн?
Re[3]: Reflection - Тип унаследованного класса из наследуемо
От: _SM_ Украина  
Дата: 23.08.05 16:23
Оценка:
Здравствуйте, Hobot Bobot, Вы писали:

HB>Здравствуйте, Аноним, Вы писали:


А>>Можно переписать вот так — тогда рефлекшн вообще не понадобиться. Вместо DataColumnCollection можно использовать MyColumnClass[]. Вообще, если работаешь с большим числом сущностей в базе полезно и удобно заводить и использовать свои метаданные об этих сущностях, а не изобретать велосипед с рефлекшеном — сильно облегчает жизнь.


HB>И как вызывать из static-метода CreateTable instance-свойство Columns?



Вот именно, хотя и его можно статиком сделать...
Решение было в следующем: создал свой класс DBManager
со статическим методом CreateTable(Type EntityType).

Тоесть, все функции для управления БД принадежат другому классу.
DBEntity обрабатывает только Exists, Open, Save.

Всем спасибо.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.