У меня есть два вопроса (которых по крайней мере один расценивает RTTI в D2010 и динамическом инстанцировании),
TRTTIConstructor.Invoke
. В смежном пункте маркированного списка каждый находит "Динамично экземпляры конструкции, не нуждаясь в виртуальных конструкторах и метаклассах". Это походит на замечательную особенность (и точно в чем я нуждаюсь, btw)! Однако, когда я смотрю в документах D2010 (ms-help://embarcadero.rs2010/vcl/Rtti.html), я не могу найти его. Это становилось отменяемым? Я думаю, что функциональные возможности были включены в TRttiMethod. Он имеет свойства IsConstructor, IsDestructor и IsClassMethod, поэтому его можно использовать как для «специальных» типов методов, так и для обычных.
Что касается вопроса 2, попробуйте что-нибудь вроде этого:
function GetConstructor(val: TRttiInstanceType): TRttiMethod;
var
method: TRttiMethod;
begin
for method in val.GetMethods('Create') do
begin
if (method.IsConstructor) and (length(method.GetParameters) = 0) then
exit(method);
end;
raise EInsufficientRTTI.CreateFmt('No simple constructor available for class %s ',
[val.MetaclassType.ClassName]);
end;
Будет найден конструктор наивысшего уровня с именем Create
, который не принимает параметров. Вы можете изменить его, чтобы искать другие конструкторы с другими подписями, если знаете, что ищете. Затем просто вызовите Invoke
для получения результата.
Хотя вы можете вызвать .GetMethod (), чтобы получить конструктор, вы также можете сделать следующее для создания экземпляров объектов без параметров для конструктора.
function CreateInstance(aType : TRttiType) : TObject;
begin
// Option #1
result := aType.AsInstance.MetaclassType.Create;
// Option #2
result := aType.GetMethod('Create').Invoke(aType.AsInstance.MetaclassType,[]);
end;
Если вы знаете базовый тип, вы можете ввести приведение класса для передачи параметров, если хотите. Вот пример создания результата Component
: = TComponentClass (aType.AsInstance.MetaClassType). Create (OwnerValue);