#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. До сих пор мне не удавалось свести проблему к простым пропорциям. Это происходит только с моим конкретным проектом в целом.