Delphi: RTTI для индексированных свойств в 2010 году? - PullRequest
3 голосов
/ 22 марта 2010

Пожалуйста, прости за многословие следующего примера кода. Используя Delphi 2009, я создал два класса TOtherClass и TMyClass:

TOtherClass = class(TObject)
public
    FData: string;
end;

TMyClass = class(TObject)
private
    FIndxPropList: Array of TOtherClass;
    function GetIndxProp(Index: Integer): TOtherClass;
    procedure SetIndxProp(Index: Integer; Value: TOtherClass);
public
    property IndxProp[Index: Integer]: TOtherClass read GetIndxProp write SetIndxProp;
end;

со спецификаторами доступа, реализованными как

function TMyClass.GetIndxProp(Index: Integer): TOtherClass;
begin
    Result := self.FIndxPropList[Index];
end;

procedure TMyClass.SetIndxProp(Index: Integer; Value: TOtherClass);
begin
    SetLength(self.FIndxPropList, Length(self.FIndxPropList) + 1);
    self.FIndxPropList[Length(self.FIndxPropList) - 1] := Value;
end;

Его использование можно проиллюстрировать следующим образом:

procedure Test();
var
    MyClass: TMyClass;
begin
    MyClass := TMyClass.Create;
    MyClass.IndxProp[0] := TOtherClass.Create;
    MyClass.IndxProp[0].FData := 'First instance.';
    MyClass.IndxProp[1] := TOtherClass.Create;
    MyClass.IndxProp[1].FData := 'Second instance.';
    MessageDlg(MyClass.IndxProp[0].FData, mtInformation, [mbOk], 0);
    MessageDlg(MyClass.IndxProp[1].FData, mtInformation, [mbOk], 0);
    MyClass.IndxProp[0].Free;
    MyClass.IndxProp[1].Free;
    MyClass.Free;
end;

Не берите в голову очевидные недостатки этого "дизайна". Я понял, что хотел бы получить доступ к свойству IndxProp через RTTI, и впоследствии переместил IndxProp в опубликованный раздел. К моему большому разочарованию, я обнаружил, что индексированные свойства не разрешены в опубликованном разделе. Насколько я понимаю (см. Комментарий Барри Келли на Как мне получить доступ к Delphi Array Properties с помощью RTTI ), переход на D2010 не позволит мне это сделать.

С другой стороны, ниже приводится цитата из Блог Роберта Лавса : "... свойства и методы теперь доступны через RTTI как в открытых, так и в опубликованных разделах, а поля доступны в все разделы . " (Мой курсив.)

У меня такой вопрос: если это правда, что можно получить RTTI для открытых полей в D2010, не должен ли мой исходный пример (как показано выше) работать в D2010 (с RTTI)? Заранее спасибо!

1 Ответ

2 голосов
/ 22 марта 2010

Да, если только средство чтения свойств выполняет индексирование в поле массива или поле списка, то вы можете использовать RTTI для непосредственного индексирования в поле.Однако это довольно хрупко, поскольку нарушает инкапсуляцию и требует написания кода для конкретной детали реализации вместо общего принципа, для которого RTTI в основном хорош.Ваш код RTTI должен соответствовать точной структуре вашего класса, и если он меняется, вы должны также изменить код.Такого рода отрицание цели использования RTTI.

Но, если нет альтернативы, так как свойства массива не имеют RTTI для них, это может быть единственный способ, по крайней мере, на данный момент.* РЕДАКТИРОВАТЬ: Обновление этого ответа.Поддержка индексированных свойств была добавлена ​​в расширенную систему RTTI в XE2.(Однако из-за проблем со стабильностью, возможно, вы захотите подождать XE3 ...)

...