使用Typinfo单元,可以轻松枚举属性,如以下代码段所示:
procedure TYRPropertiesMap.InitFrom(AClass: TClass; InheritLevel: Integer = 0);
var
propInfo: PPropInfo;
propCount: Integer;
propList: PPropList;
propType: PPTypeInfo;
pm: TYRPropertyMap;
classInfo: TClassInfo;
ix: Integer;
begin
ClearMap;
propCount := GetPropList(PTypeInfo(AClass.ClassInfo), propList);
for ix := 0 to propCount - 1 do
begin
propInfo := propList^[ix];
propType := propInfo^.PropType;
if propType^.Kind = tkMethod then
Continue; // Skip methods
{ Need to get GetPropInheritenceIndex to work
if GetPropInheritenceIndex(propInfo) > InheritLevel then
Continue; // Dont include properties deeper than InheritLevel
}
pm := TYRPropertyMap.Create(propInfo.Name);
FList.Add(pm);
end; …Run Code Online (Sandbox Code Playgroud) 我有一个发布道具的类,我将其序列化为XML.
MyAttr = class(TCustomAttribute)
private
FName: string;
public
constructor Create(const Name: string);
property Name: string read FName write FName;
end;
MyClass = class(TPersistent)
private
FClassCaption: string;
published
[MyAttr('Class')]
property ClassCaption: string read FClassCaption write FClassCaption;
end;
Run Code Online (Sandbox Code Playgroud)
由于XML大小至关重要,我使用属性为属性提供更短的名称(即我无法定义名为'Class'的属性).序列化通过以下方式实现:
lPropCount := GetPropList(PTypeInfo(Obj.ClassInfo), lPropList);
for i := 0 to lPropCount - 1 do begin
lPropInfo := lPropList^[i];
lPropName := string(lPropInfo^.Name);
if IsPublishedProp(Obj, lPropName) then begin
ItemNode := RootNode.AddChild(lPropName);
ItemNode.NodeValue := VarToStr(GetPropValue(Obj, lPropName, False));
end;
end;
Run Code Online (Sandbox Code Playgroud)
我需要条件:如果属性标记为MyAttr,则获取"MyAttr.Name"而不是"lPropInfo ^ .Name".
我最近在这个论坛上发布了一个问题,询问有关DXE2可执行文件中缺少RTTI信息的任何建议.
那篇文章是我实际案例的精简版.RRUZ来救援,因此被剥离的版本很快得到了解决.但是,最初的问题仍然存在,所以我现在正在全力发布."主要":
program MissingRTTI;
{$APPTYPE CONSOLE}
uses
System.SysUtils, RTTI, MyUnit in 'MyUnit.pas', RTTIUtil in 'RTTIUtil.pas';
var
RHelp: TRttiHelper;
begin
RHelp := TRttiHelper.Create();
if (RHelp.IsTypeFound('MyUnit.TMyClass')) then WriteLn('TMyClass was found.')
else WriteLn('TMyClass was not found.');
ReadLn;
RHelp.Free();
end.
Run Code Online (Sandbox Code Playgroud)
RTTIUtil.pas:
unit RTTIUtil;
interface
uses
MyUnit;
type
TRttiHelper = class(TObject)
public
function IsTypeFound(TypeName: string) : boolean;
end;
implementation
uses
RTTI;
function TRttiHelper.IsTypeFound(TypeName: string): boolean;
var
rCtx: TRttiContext;
rType: TRttiType;
begin
Result := false;
rCtx := TRttiContext.Create();
rType := rCtx.FindType(TypeName);
if (rType …Run Code Online (Sandbox Code Playgroud) 因为我们可以找到一个Property或者一个Object使用RTTI,我们可以在内存中搜索某个function或者procedure(不是来自一个对象method但是来自一个unit)知道它的名字吗?
如果我们可以,是否可以执行它发送它的参数?
只是为了确保我没有忽略一个奇怪的边缘情况,因为我发现了一个产生它的情况,但我想确保:
是否有任何Delphi版本可以发出包含类型tkUnknown为TTypeKind的 RTTI ?
如果是这样:
在当前的Delphi XE5 RTL,我能找到处理的唯一地方tkUnknown是TValue,但我还没有发现在RTL,设置了一个代码路径TValue包含所属类别有tkUnknown作为类.
我正在尝试为Delphi和.NET编写通用的消息传递系统.系统允许将消息定义为普通对象,并将消息处理程序定义为对这些对象起作用的匿名方法.
对象将转换为JSON,并在同一台计算机上运行的应用程序之间传递.每个应用程序都维护一个理解特定消息类型的处理程序列表.
我的类有许多参数化注册方法.有些采用单一类型参数.有些参数采用一对参数,其中一个表示请求对象,另一个表示响应对象.以下是请求/响应处理程序注册的内容:
procedure TTelegraph.RegisterRequestHandler<TRequest, TResponse>
(requestTypeToHandle: string; handler: TFunc<TRequest, TResponse>);
begin
FRequestHandlers.Add(requestTypeToHandle,
TRequestHandler<TRequest, TResponse>.Create(handler,
TRequest,
TResponse));
end;
Run Code Online (Sandbox Code Playgroud)
FRequestHandlers是一个TDictionary<string,TRequestHandler>.注册方法如下调用:
FTelegraph.RegisterRequestHandler<TTestRequest, TTestResponse>('My Request',
function(x: TTestRequest): TTestResponse
begin
Result := TTestResponse.Create;
Result.Number := x.Number;
Result.Message := Format('Received: %s', [x.Message]);
end);
Run Code Online (Sandbox Code Playgroud)
泛型TRequestHandler<T1,T2>是一个DTO,它包含处理程序以及类型TRequest和TResponse.它继承自非泛型TRequestHandler.我不确定是否有更好的方法可以解决这个问题,但这是我能想到的在单个集合中存储多个不相关类型的唯一方法.
这一切似乎都很好.问题是收到请求消息时.处理请求消息的C#代码如下所示:
private void ProcessRequestTelegram(Telegram request)
{
var requestType = _RequestHandlers[request.MessageType].RequestType;
var typedRequest = JsonConvert.DeserializeObject(request.Payload, requestType);
var result = _RequestHandlers[request.MessageType].Handler.DynamicInvoke(typedRequest);
var jsonPayload = JsonConvert.SerializeObject(result);
var response = new Telegram()
{
Payload …Run Code Online (Sandbox Code Playgroud) 我很感激之前已经提出过几个类似的问题:
但是,我没有进一步了解如何将RTTI用于我的需求.
我也花了很多时间和精力来写这个问题所以我希望它不会被关闭:)
我在下面有几个过程可以输出到TStrings列表中的组件的属性名称,值和类型.原始来源不是我的,我只是做了一些小改动,整理了代码并将它们放入一些整洁的可重用程序:
下面将输出属性名称,例如:
- 颜色
- DoubleBuffered
- 启用
- 高度
- 宽度
procedure GetComponentPropertyNames(Component: TComponent; OutList: TStrings);
var
I: Integer;
Count, Size: Integer;
PropList: PPropList;
PropInfo: PPropInfo;
begin
OutList.BeginUpdate;
try
OutList.Clear;
Count := GetPropList(Component.ClassInfo, tkAny, nil);
Size := Count * SizeOf(Pointer);
GetMem(PropList, Size);
try
Count := GetPropList(Component.ClassInfo, tkAny, PropList);
for I := 0 to Count -1 do
begin
PropInfo := PropList^[I];
if not (PropInfo^.PropType^.Kind = tkMethod) then
begin
OutList.Add(PropInfo^.Name);
end;
end;
finally
FreeMem(PropList);
end;
finally
OutList.EndUpdate; …Run Code Online (Sandbox Code Playgroud) 我曾问过一个问题C++ POD类型有RTTI吗?有人在评论中告诉我:
POD类型确实有type_info,但没有RTTI,这是可能的,因为type_info并不总是RTTI.
它似乎是正确的,因为我可以获得type_infoPOD(非多态)类型.
但是当我编译这个简单的程序时:
#include <iostream>
struct X
{
int a;
};
int main()
{
using namespace std;
std::cout << typeid(X) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
与-fno-rtti海湾合作委员会的旗帜:
$ g++ -fno-rtti main.cpp && ./main
Run Code Online (Sandbox Code Playgroud)
它不会编译:
main.cpp: In function ‘int main()’:
main.cpp:12:26: error: cannot use typeid with -fno-rtti
std::cout << typeid(X) << std::endl;
^
Run Code Online (Sandbox Code Playgroud)
这是否意味着type_info是RTTI的一部分,还是仅仅是GCC 的行为?
我的功能模块在运行时会收到一个表名和一个列名。
我想获取列的长度:透明表中允许多少个字符?
我使用了我最喜欢的搜索引擎,并发现了RTTS。
但是文档中的例子将变量传递给RTTS方法DESCRIBE_BY_DATA; 就我而言,我没有变量,而在table_name和中只有类型名称column_name。
如何获得长度?
让我们看看示例类。基类是ITransport,传输类接口:
class ITransport {
public:
virtual void move(const Path& p) = 0;
virtual double estimateTime(const Path& path) = 0;
/*Some more methods.*/
};
Run Code Online (Sandbox Code Playgroud)
执行:
class Transport : public ITransport {
public:
virtual void move(const Path& p) override {
currPoint_ = p.lastPoint();
}
/*Some more methods.*/
private:
Point currPoint_;
};
Run Code Online (Sandbox Code Playgroud)
我们还假设我们要创建一个自移动的运输类:
template <typename EnergySource>
class SelfMovingTransport : public Transport {
/*Some special methods for self moving transport.*/
};
Run Code Online (Sandbox Code Playgroud)
自动运输最简单的例子是汽车:
template <typename EnergySource>
class Car : public SelfMovingTransport <EnergySource> { …Run Code Online (Sandbox Code Playgroud) rtti ×10
delphi ×7
c++ ×2
delphi-xe7 ×2
abap ×1
attributes ×1
c++17 ×1
delphi-xe2 ×1
delphi-xe3 ×1
enumeration ×1
gcc ×1
generics ×1
json ×1
properties ×1
sap ×1