Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Список полей класса. Можно как то получить в runtime?


Страницы:   1 2 3

Begin ©   (2005-06-27 17:14:00) 

GetPropList(self.ClassInfo... и т.д. не сработал. Вернее, сработал, но только для получения published-свойств... А можно ли как то получить список тех полей, которые не-published ???

Вот к примеру :

TSomeClass = class
 field1 : integer; //Вот эти поля сильно охота
 field2 : integer; //получить в runtime
 published
   property prop1; // это вот GetPropList'ом возвращется,
                   // только надо не его...
end;


Спасибо заранее...


default   (2005-06-27 19:12:00) [21]

jack128 ©   (27.06.05 19:06) [35]
а нафиг?
всё равно для целей автора это ничё не даст поскольку поиск будет каждый раз вестись...
он хочет невозможного по ходу


jack128   (2005-06-27 19:06:00) [22]

Юрий Зотов ©   (27.06.05 18:51) [31]
Есть сомнения, что поколдовав над исходниками FieldAddress мы получим таки список полей ??  К сожелению сейчас зашиваюсь, но через недельку думаю преставлю исходники.  Есть в System.pas такая структурка - PFieldTable, вот из неё информация и вытаскивается, только там формат не очевидный..


Суслик   (2005-06-27 18:55:00) [23]

да, наверное я не о том :))
но все равно - может кому полезно будет.


Суслик   (2005-06-27 18:53:00) [24]

методы можно так перечислить
поля - не знаю.

//
// TMethodEnumerator
//

// from dUnit.pas from Delphi2005

type   TMethodEnumerator = class

     protected FMethodNameList: array of string;
     protected function GetNameOfMethod(Index: integer):  string;
     protected function GetMethodCount: Integer;

     public constructor Create(AClass: TClass);
     public property MethodCount: integer read GetMethodCount;
     public property NameOfMethod[index:  integer]: string read GetNameOfMethod;
  end;

constructor TMethodEnumerator.Create(AClass: TClass);
type
  TMethodTable = packed record
     count: SmallInt;
  end;
var
  table: ^TMethodTable;
  name:  ^ShortString;
  i, j:  Integer;
begin
  inherited Create;
  while aclass <> nil do
  begin
     // *** HACK ALERT *** !!!
     // Review System.MethodName to grok how this method works
     asm
        mov  EAX, [aclass]
        mov  EAX,[EAX].vmtMethodTable { fetch pointer to method table }
        mov  [table], EAX
     end;
     if table <> nil then
     begin
        name  := Pointer(PChar(table) + 8);
        for i := 1 to table.count do
        begin
           // check if we've seen the method name
           j := Low(FMethodNameList);
           while (j <= High(FMethodNameList)) and (name^ <> FMethodNameList[j]) do
              inc(j);

           // if we've seen the name, then the method has probably been overridden
           if j > High(FMethodNameList) then
           begin
              SetLength(FMethodNameList,length(FMethodNameList)+1);
              FMethodNameList[j] := name^;
           end;
           name := Pointer(PChar(name) + length(name^) + 7)
        end;
     end;
     aClass := aClass.ClassParent;
  end;
end;

function TMethodEnumerator.GetMethodCount: Integer;
begin
  Result := Length(FMethodNameList);
end;

function TMethodEnumerator.GetNameOfMethod(Index: integer): string;
begin
  Result := FMethodNameList[Index];
end;


Юрий Зотов   (2005-06-27 18:52:00) [25]

> Суслик ©   (27.06.05 18:42) [29]

Тоже см. [31].


Юрий Зотов   (2005-06-27 18:51:00) [26]

> jack128 ©   (27.06.05 18:19) [23]
> DiamondShark ©   (27.06.05 18:40) [27]

Не считаю правильным заниматься формальными придирками к словам, выдергивая их из контекста ветки. И ежику известно, что есть FieldAddress и пр. Но здесь-то ведь речь идет о получении списка полей?  Неужто не понятно, что это и имелось в виду.

Если не согласны - прошу привести код, дающий список published-полей. Как вы понимаете, список published-свойств получается легким движением руки - а вот как быть с полями?

Сорри, но лучше бы по делу что сказали...


default   (2005-06-27 18:49:00) [27]

может тебе понравится создание объектов через ссылку на класс их общего класса при наличие виртуальных конструкторов
хотя всё равно придётся "забить" массив ссылок на класс создаваемых типов


Суслик   (2005-06-27 18:42:00) [28]

для методов тоже генерится.


default   (2005-06-27 18:40:00) [29]

"Эт я для наглядности, только в форуме. Все равно ведь придется имена полей перечислить, и вызвать для каждого Create."
ёлки, ну так сделай массив объектов и в цикле обходи и вызывай свои конструкторы...


DiamondShark   (2005-06-27 18:40:00) [30]


> Юрий Зотов ©   (27.06.05 17:28) [10]
> Уточнение.
>
> Все эти списки основаны на RTTI, а она генерится только
> для свойств (а не для полей)

Не правда.
Она генерится для всего, что паблишед.


begin...end   (2005-06-27 18:32:00) [31]

> Begin   (27.06.05 18:19) [24]

> В смысле ?

В смысле, есть методы класса , объявленные со словом class, например:

TOneClass = class
  classprocedure Init(...);
end;


а есть обычные методы (объявленные без слова class)-- методы объекта .
Вот и непонятно, как можно обычный метод объекта вызвать в форме TOneClass.init(1), т.е.   Имя_Класса.Имя_Метода, а не в форме Имя_Экземпляра_Класса.Имя_Метода. Компилятор такое мог пропустить только для классового метода (или для конструктора, который тоже, в общем-то, по сути дела является классовым методом).


Begin   (2005-06-27 18:22:00) [32]


> jack128 ©   (27.06.05 18:19) [23]
> Юрий Зотов ©   (27.06.05 17:28) [10]
> а она генерится только для свойств (а не для полей),  Э-э-э..
> TObject.FieldAddress ??  


FieldAddress method (TObject)

Returns the address of a publishedobject field.


Begin   (2005-06-27 18:19:00) [33]


> begin...end ©   (27.06.05 18:12) [22]
> > Begin   (27.06.05 17:49) [16]
> > TOneClass.init(1);
> Init -- это классовый метод, что ли?


Ээээ... В смысле ? Некоторые поля - экземпляры других классов, init - это их метод. Неклассовых методов не встречал... :))


> Eraser ©   (27.06.05 18:09) [21]
> Begin
>
> 1. Лучше использовать оператор case.
> 2. init перенести в конструктор создаваемого объекта.

Эт я для наглядности, только в форуме. Все равно ведь придется имена полей перечислить, и вызвать для каждого Create.


jack128   (2005-06-27 18:19:00) [34]

Юрий Зотов ©   (27.06.05 17:28) [10]
а она генерится только для свойств (а не для полей),
 Э-э-э.. TObject. FieldAddress ??  
Begin   (27.06.05 17:14)
Поищи на delphikingdom статью про создание инспектора объектов. Там как раз реализовывалось что похожее на предложенное Юрой Зотовым..


begin...end   (2005-06-27 18:12:00) [35]

> Begin   (27.06.05 17:49) [16]

> TOneClass.init(1);

Init -- это классовый метод, что ли?


Eraser   (2005-06-27 18:09:00) [36]

Begin

1. Лучше использовать оператор case.
2. init перенести в конструктор создаваемого объекта.


Begin   (2005-06-27 18:08:00) [37]


> Юрий Зотов ©   (27.06.05 17:47) [15]

> Уменьшить список полей в потомке, как Вы понимаете, невозможно,
> его можно только увеличить. Для уменьшения же в любом случае
> придется править код - в том числе, и эти 2 метода.


Это да, понимаю. Просто объем изменений мог бы быть много меньше.


Begin   (2005-06-27 18:05:00) [38]


> Digitman ©   (27.06.05 17:52) [18]
>
> > Begin   (27.06.05 17:49) [16]
>
> какую роль играет поле SelfStatus ?
> где и как оно иниц-ся ?


Если 0 - готовить пустую форму для приема данных. Если 1 - получить данные из БД и разрешить их менять. Если 2 - получить из БД и показать в режиме только просмотра. Инициируется после создания базового класса в зависимости от установок программы.


Digitman   (2005-06-27 17:52:00) [39]


> Begin   (27.06.05 17:49) [16]


какую роль играет поле SelfStatus ?
где и как оно иниц-ся ?


Eraser   (2005-06-27 17:52:00) [40]

Begin   (27.06.05 17:49) [16]

А зачем init(1)?????


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо