有没有办法用Rtti探索界面的属性?
以下代码不起作用:
procedure ExploreProps;
var
Ctx: TRttiContext;
RttiType: TRttiType;
RttiProp: TRttiProp;
begin
RttiType := Ctx.GetType(TypeInfo(IMyInterface));
for RttiProp in RttiType.GetProperties do
Writeln(RttiProp.ToString);
end;
Run Code Online (Sandbox Code Playgroud)
有没有人解决方法如何正确地做到这一点?
我有一个指向对象的指针列表.这些对象没有任何共同之处(即没有共同的基类); 为了更好地理解:它是GUI中鼠标光标下的对象列表.
现在我想知道它是什么样的物体.节点,节点句柄,线段,标记等.但是我不能使用,typeid(*ptr)因为ptr是一个const void*.
对此有何解决方案?我可以强制使用typeid,因为我知道指针始终指向对象而不仅仅是值?或者没有办法添加一些假的共同基类?
(编辑:目前我正在这样做,我在列表中存储一个结构,另外存储对象的类型(作为枚举).也许我应该更改它来存储一个type_info对象...)
我们可以使用SuperObject库通过名称调用某个对象的方法,并使用SOINvoker方法将其参数作为json字符串给出,就像在这个答案中一样
我想知道如何将创建的对象作为参数发送.我试着像发送它一样
LObjectList := TObjectList.Create;
LSuperRttiCtx := TSuperRttiContext.Create;
LSuperObjectParameter := LObjectList.ToJson(LSuperRttiCtx);
SOInvoke(MyInstantiatedObject, 'MyMethod', LSuperObjectParameter);
Run Code Online (Sandbox Code Playgroud)
但在MyMethod内部,LObjectList引用丢失了.
我究竟做错了什么?
superobject库可以在这里下载
在我看来,TValue中缺少一个强制性方法; TValue.Equals(TValue).
因此,比较2个TValues的快速和体面的方式,最好不使用TValue.ToString(),它允许变体,记录等之间的错误匹配.
使用Delphi 2010中的新扩展RTTI,Delphi应用程序(在运行时)是否可以构建实现给定接口的所有类的列表?
我有两个问题(其中至少有一个是关于D2010中的RTTI和动态实例)
TRTTIConstructor.Invoke.在相邻的项目符号点中,可以找到"动态构造实例而无需虚拟构造函数和元类".这似乎是一个很棒的功能(正是我需要的,顺便说一下)!但是,当我查看D2010文档(ms-help://embarcadero.rs2010/vcl/Rtti.html)时,我找不到它.它被撤销了吗?我想创建一个表单,将其类名称作为字符串,之前已经被问过,但是GetClass我想使用Delphi的新RTTI功能而不是调用.
有了这段代码,我有一个TRttiType,但我不知道如何实例化它.
var
f:TFormBase;
ctx:TRttiContext;
lType:TRttiType;
begin
ctx := TRttiContext.Create;
for lType in ctx.GetTypes do
begin
if lType.Name = 'TFormFormulirPendaftaran' then
begin
//how to instantiate lType here?
Break;
end;
end;
end;
Run Code Online (Sandbox Code Playgroud)
我也试过lType.NewInstance没有运气.
在以下类型中:
MyClass = class(TInterfacedPersistent)
private
FMyProperty: Integer;
published
procedure setMyProperty(Value: Integer); virtual;
property MyProperty: Integer read FMyProperty write setMyProperty;
Run Code Online (Sandbox Code Playgroud)
我想通过RTTI知道"MyProperty"属性的setter方法的名称.我尝试过以下方法:
procedure ShowSetterMethodsNames(pMyObject: TObject);
var
vPropList: TPropList;
vCount, I: Integer;
begin
vCount:= GetPropList(pMyObject.ClassInfo, tkProperties, @vPropList);
for I:= 0 to vCount -1 do
begin
if Assigned(vPropList[I]^.SetProc) then
ShowMessage(pMyObject.ClassType.MethodName(vPropList[I]^.SetProc));
end;
end;
Run Code Online (Sandbox Code Playgroud)
虽然指针不是nil,但我所有的都是空消息.有人给我一些小费吗?
PS:我正在使用Delphi XE4,我知道我应该使用扩展RTTI而不是经典,但无论如何,我不能在两个功能中做我想要的...所以,任何帮助将不胜感激.谢谢你的回复.
最终版,问题解决了:
这是代码工作,基于(我的朋友和...的帮助)RTTI单元(TRTTIInstanceProperty类的DoSetValue方法):
procedure ShowVirtualSettersNames(pObject: Pointer);
var
vSetter, vPointer: Pointer;
vPropList: TArray<TRttiProperty>;
vProp: TRttiProperty;
begin
vPropList:= RTTIUtils.ExtractProperties(TObject(pObject).ClassType); // Helper to get properties from a type, based in extended RTTI
for …Run Code Online (Sandbox Code Playgroud) 我已经定义了以下内容:
方法指针,如果验证正常或错误代码,则返回0
TValidationFunc = Function(AParam: TAnObject): integer Of Object;
Run Code Online (Sandbox Code Playgroud)要执行的函数列表:
Functions: TObjectList < TValidationFunc>;
Run Code Online (Sandbox Code Playgroud)我在函数列表中放了几个带有此签名的函数.
要执行它们,我执行:
For valid In Functions Do
Begin
res := -1;
Try
res := valid(MyObject);
Except
On E: Exception Do
Log('Error in function ??? : ' + E.Message, TNiveauLog.Error, 'PHVL');
End;
Result := Result And (res = 0);
End;
Run Code Online (Sandbox Code Playgroud)
如果此函数引发异常,我如何在日志中获取原始函数的名称?
我如何在TVirtualInterface类的OnInvoke方法中获得Method:TRttiMethod的所有权属性?
我有这个界面:
IPerson = interface(IInvokable)
['{45CE428C-F880-4D61-A2C1-0F3CB47130B5}']
procedure SetName(const Value: string);
function GetName(): string;
[TEntityField('Field Name Here')]
property Name: string read GetName write SetName;
end;
Run Code Online (Sandbox Code Playgroud)
而这堂课:
type
TVirtualEntity<T: IInvokable> = class(TVirtualInterface)
public
constructor Create(); reintroduce; overload;
end;
constructor TVirtualEntity<T>.Create;
begin
inherited Create(TypeInfo(T));
Self.OnInvoke :=
procedure(Method: TRttiMethod; const Args: TArray<TValue>; out Result: TValue)
var
attributes: TArray<TCustomAttribute>;
attributesManager: TAttributesManager;
entityFieldAttribute: TEntityField;
begin
attributesManager := TAttributesManager.Create(Method.GetAttributes);
try
if attributesManager.HasAttribute<TEntityField>() then
begin
Result := attributesManager.GetAttribute<TEntityField>.FieldName;
end;
finally
attributesManager.Free;
end;
end;
end;
Run Code Online (Sandbox Code Playgroud)
我想获得方法的TRttiProperty:TRttiMethod,但是怎么样?如果我将界面更改为:
IPerson = interface(IInvokable) …Run Code Online (Sandbox Code Playgroud) rtti ×10
delphi ×9
delphi-2010 ×2
interface ×2
reflection ×2
c++ ×1
delegates ×1
delphi-xe ×1
delphi-xe2 ×1
delphi-xe4 ×1
equality ×1
superobject ×1
tvalue ×1