Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Обработка исключений `EInvalidCastException` при использовании RTTI в Delphi

Delphi , Компоненты и Классы , RTTI

Обработка исключений EInvalidCastException при использовании RTTI в Delphi

При работе с отражением типов (RTTI) в Delphi может возникнуть исключение EInvalidCastException. Это происходит, когда пытаются присвоить свойству типа procedure of object значение через TRttiProperty.SetValue. В данном случае пользователь столкнулся с такой проблемой, пытаясь назначить процедуру объекту через RTTI.

Контекст проблемы

Пользователь столкнулся с проблемой, когда пытался назначить свойство типа procedure of object через механизмы RTTI. Пример кода, представленный в вопросе, демонстрирует возникновение исключения EInvalidCastException при попытке установить значение свойства с помощью TRttiProperty.SetValue.

uses
  Rtti,
  SysUtils;

type
  TMyCallBack = procedure(const Foo: string) of object;
  TMyClass = class
    procedure DoSomething(const Foo: String);
  end;

  TMyAnotherClass = class
  private
    FDoSomething: TMyCallBack;
  published
    property DoSomething: TMyCallBack read FDoSomething Write FDoSomething;
  end;

procedure TMyClass.DoSomething(const Foo: String);
begin
  Writeln('Hello');
end;

var
  MyClass: TMyClass;
  t: TRttiInstanceType;
  v: TValue;
  p: TRttiProperty;
  Bar: TMyCallBack;
begin
  try
    MyClass:=TMyClass.Create;
    try
      t:=TRttiContext.Create.GetType(TMyAnotherClass).AsInstance;
      v:=t.GetMethod('Create').Invoke(t.MetaclassType,[]);
      p:=t.GetProperty('DoSomething');
      Bar:=MyClass.DoSomething;
      if p <> nil then
        p.SetValue(v.AsObject, @Bar); // здесь возникает исключение
    finally
      MyClass.Free;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

Подтвержденный ответ

При анализе возникшей ошибки было выявлено, что проблема связана с некорректным преобразованием указателя на процедуру в TValue. В коде необходимо было создать TValue, который бы точно соответствовал типу и значению процедуры. Исправленный код выглядит следующим образом:

var
  vBar: TValue;
begin
  // ...
  vBar := TValue.From<TMyCallBack>(Bar);
  if p <> nil then
    p.SetValue(v.AsObject, vBar); // теперь исключение не возникает
  // ...
end.

Альтернативный ответ

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

Заключение

При работе с RTTI в Delphi важно правильно обрабатывать значения типов procedure of object. Необходимо создавать TValue, который соответствует типу процедуры, и использовать метод TValue.From для корректного преобразования. Это позволит избежать возникновения исключений EInvalidCastException при использовании TRttiProperty.SetValue.

Учитывая специфику Object Pascal и Delphi, разработчикам стоит быть внимательными при работе с RTTI, особенно при преобразованиях указателей на процедуры в TValue.

Создано по материалам из источника по ссылке.

Пользователь столкнулся с исключением `EInvalidCastException` при попытке назначить процедуру объекту через механизмы отражения типов (RTTI) в Delphi.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: RTTI ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-02-05 21:06:39/0.0030980110168457/0