Обработка исключений 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
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.