+1 за

реймворка я написал оболочку, которая использует любой объект, интерфейс или тип записи для исследования его свойств или полей. Объявление класса выглядит следующим образом:

TWrapper<T> = class 
private
  FType : TRttiType;
  FInstance : Pointer;
  {...}
public
  constructor Create (var Data : T);
end;

В конструкторе я пытаюсь получить информацию о типе для дальнейших шагов обработки.

constructor TWrapper<T>.Create (var Data : T);
begin
FType := RttiCtx.GetType (TypeInfo (T));
if FType.TypeKind = tkClass then
  FInstance := TObject (Data)
else if FType.TypeKind = tkRecord then
  FInstance := @Data
else if FType.TypeKind = tkInterface then
  begin
  FType := RttiCtx.GetType (TObject (Data).ClassInfo); //<---access violation
  FInstance := TObject (Data);
  end
else
  raise Exception.Create ('Unsupported type');
end;

Интересно, является ли это нарушение доступа ошибкой в ​​компиляторе Delphi (я использую XE). После дальнейшего исследования я написал простую тестовую функцию, которая показывает, что запрос имени класса также вызывает это исключение:

procedure TestForm.FormShow (Sender : TObject);
var
  TestIntf : IInterface;
begin
TestIntf    := TInterfacedObject.Create;
OutputDebugString(PChar (TObject (TestIntf).ClassName)); //Output: TInterfacedObject
Test <IInterface> (TestIntf);
end;

procedure TestForm.Test <T> (var Data : T);
begin
OutputDebugString(PChar (TObject (Data).ClassName)); //access violation
end;

Может кто-нибудь объяснить мне, что не так? Я также попробовал процедуру без параметра var, который тоже не работал. При использовании не универсальной процедуры все работает нормально, но для упрощения использования обертки было бы неплохо универсальное решение, потому что оно работает для объектов и записей одинаково.

С уважением,

Кристиан

Ответы на вопрос(2)

Ваш ответ на вопрос