-
Здравствуйте, товарищи кодеры. Подскажите, как можно получить список всех полей переменной типа record (либо проверить существование поля по переданному названию)? Нужно что-то вроде этого: TMyRecord = record
A, B: String;
C: integer;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
obj: TMyRecord;
props: array [0..2] of string;
begin
props := PropertyList(obj);
end;
-
В Delphi из готовых механизмов это доступно только для полей класса, тип которых (полей) есть published. Ключевые слова для чтения: RTTI
-
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses Rtti;
type TMyRecord = record A, B: string; C: integer; end;
var rType: TRttiRecordType; I: Integer; begin rType := TRttiRecordType(TRTTIContext.Create.GetType(TypeInfo(TMyrecord))); for I := 0 to Length(rType.GetDeclaredFields) - 1 do Writeln(rType.GetDeclaredFields[I].ToString); Readln; end.
-
ЗЫ: это начиная с XE работает, на старых - врятли (тестировал на XE4)
-
-
все как обычно под луной......
приходит чел с неправильным дизайном и вытекающим из него вопросом. и ему таки подсказывают как удалить гланды не через горло.
вот скажи, если уж тебе нужны имена значений и нужно проверять лежит ли про указателю та структура, которую ты ожидаешь,
то нафига же ты выбираешь рекорд для своей задачи?
-
Очень интересный ответ, а вот скажи мне, для чего вообще в rtti ввели данную возможность? :)
-
> ЗЫ: это начиная с XE работает, на старых - врятли (тестировал > на XE4)
Мне для классической семёрки надо.
> вот скажи, > если уж тебе нужны имена значений и нужно проверять лежит > ли про указателю та структура, которую ты ожидаешь, > > то нафига же ты выбираешь рекорд для своей задачи?
Посчитал что с ним будет проще.
Сейчас вкратце расскажу суть задачи. Есть сущности "Тип задания". Их несколько штук. У каждой есть некоторые поля - причём часть из них встречается во всех или больше чем в одном типе. Эти свойства нужно менять через графический интерфейс. Мне пришла самая простая идея сделать так. Создать массив с record-ами. Потом в форме есть combobox - "Название типа задания". Также на форме есть поля для редактировния свойств из всех типов. При переключении комбобокса, в контролы подгружаются значения полей выбранного типа, а если "тип" данное свойство не использует, тогда Enabled:=False. При этом вручную добавил многочисленные IF-ы, проверяющие используется ли это поле для текущего "типа" или нет. Очень похожая мешанина кода при сохранении (обратно в массив да ещё в ini файл) и ещё в одном месте. Отсюда возникло желание как-то упростить это дело. Идея такая, чтобы при отображении/сохранение проходить по всем свойствам выбранного объекта - если свойство есть - отображать/сохранять, если нет - поле делать неактивным.
Очень сумбурно объяснил, но думаю можно понять ) У кого-нибудь есть варианты как это ещё можно организовать?
-
> У кого-нибудь есть варианты как это ещё можно организовать?
Программиста пригласить, например
-
Лучше - пристрелить таких и с такими вопросами.
-
> iop © (26.10.16 20:39) [5] > > все как обычно под луной...... > > приходит чел с неправильным дизайном
А при чём тут "дизайн"?
-
А при чём тут "дизайн"?
о нифига себе вопросики на форуме программеров. чувак построил дом трехэтажный, со входом с чердака. и теперь немного неудобно и есть вопросы
ему предложили подумать, а правильный ли дизайн выбран. но тут приходит строитель и говорит, да при чем здесь какой-то дизайн, когда надо просто траволатор-эскалатор на чердак с земли прокинуть
-
> но тут приходит строитель и говорит,
Но ведь мы, строители, так и работаем :)
-
Artem78, структуры не самый удачный выбор для такой унификации.
Я бы реализовал 3 класса TAttribute, TTask и TTaskList.
TAttribute = class public Name: String; Value: String; end;
TTask = class(TList) private funcrion GetAttributes(i: Integer): TAttribute; public Name: String; property Attributes[i: Integer]: TAttribute read GetAttributes; default; end;
TTaskList = class(TList) private funcrion GetTasks(i: Integer): TTask; public property Tasks[i: Integer]: TTask read GetTasks; default; end;
Собственно и все список задач в твой ComboBox загружаешь из TaskList. При выборе задачи из списка: "Task:= TaskList[ ComboBox.ItemIndex ];" А там:
// Для всех Control-ов "Enableb:= False"; for i:= 0 to Task.Count-1 do begin if Task[i].Name = 'prm1' then Control1.Enableb:= True; if Task[i].Name = 'prm2' then Control2.Enableb:= True; . . . if Task[i].Name = 'prmN' then ControlN.Enableb:= True; end;
|