Неправильная информация о видимости RTTI и отсутствующие атрибуты

#delphi #attributes #visibility #delphi-xe #rtti

#delphi #атрибуты #видимость #delphi-xe #rtti

Вопрос:

По сути, в моем приложении есть следующий класс

 TCategory = class(TAbstractionTreeItem)
  private
    fName: String;
    fParent: Integer;
    fComment: String;
  public
    procedure Default; override;
  protected
    procedure Validate(Validation: TValidation); override;
  published
    [AbstractionField]
    property Name: string read fName write fName;
    [AbstractionField]
    property Parent: Integer read fParent write fParent;
    [AbstractionField]
    property Comment: String read fComment write fComment;
  end;
  

Когда я теперь пытаюсь получить информацию о с помощью расширенного RTTI в Delphi XE, я получаю в качестве информации о видимости для опубликованных свойств результат, который сообщает мне, что они являются общедоступными, а атрибуты, которые я добавил, вообще не отображаются.

Что там происходит? Я уже пытался проверить, что это правильный класс, который я пытаюсь проанализировать, и что принадлежащий ему модуль перекомпилируется при возникновении изменений. Похоже, проблема не в этом.

Ответ №1:

Чтобы ваш код был предоставлен для компиляции, я изменил следующее:

 AbstractionField = class(TCustomAttribute)
end;

TCategory = class(TObject)
  private
    fName: String;
    fParent: Integer;
    fComment: String;
  public
    procedure Default; 
  protected
    procedure Validate(Validation: Integer); 
  published
    [AbstractionField]
    property Name: string read fName write fName;
    [AbstractionField]
    property Parent: Integer read fParent write fParent;
    [AbstractionField]
    property Comment: String read fComment write fComment;
  end;
  

Затем я написал следующий код для запроса видимости свойств:

 var
 C : TRttiContext;
 T : TRttiType;
 P : TRttiProperty;

begin
  T := C.GetType(TCategory.ClassInfo);
  for P in T.GetProperties do
  begin
     Memo1.Lines.Add(P.Name   ' '   
                     GetEnumName(TypeInfo(TMemberVisibility),ord(P.Visibility)) );
  end;
end;
  

Мои результаты, где (как и ожидалось):

 Name mvPublished
Parent mvPublished
Comment mvPublished
  

Я также использую Delphi XE, вам придется предоставить больше кода, чтобы мы могли дублировать проблему.

Также убедитесь, что вы проверили свои предупреждения на наличие: [Предупреждение DCC] UnitName.pas (LineNum): W1025 Неподдерживаемая языковая функция: ‘пользовательский атрибут’

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

Комментарии:

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

2. Кажется, в моем случае компилятор просто время от времени путается по какой-то неизвестной причине. Что, кажется, помогает, так это дружески напомнить ему о его обязанностях, поместив {$RTTI INHERIT PROPERTIES([vcPublic, vcPublished])} в базовый класс TCategory. До сих пор мне не удавалось свести проблему к простым пропорциям. Это происходит только с моим конкретным проектом в целом.