Delphi 如何发布RTL单元的私有类函数?
Delphi XE3,System.Rtti.pas 我需要访问两个私有类函数,但我已经读到,如果我修改一个RTL单元的接口部分,那么我需要重新编译所有的RTL。不适合胆小的人 System.Rtti.pas中有两个私有类函数:Delphi 如何发布RTL单元的私有类函数?,delphi,Delphi,Delphi XE3,System.Rtti.pas 我需要访问两个私有类函数,但我已经读到,如果我修改一个RTL单元的接口部分,那么我需要重新编译所有的RTL。不适合胆小的人 System.Rtti.pas中有两个私有类函数: class function GetName<T{: enum}>(AValue: T): string; reintroduce; static; class function GetValue<T{: enum}>(const
class function GetName<T{: enum}>(AValue: T): string; reintroduce; static;
class function GetValue<T{: enum}>(const AName: string): T; static;
类函数GetName(AValue:T):字符串;重新引入;静止的
类函数GetValue(const AName:string):T;静止的
System.Rtti.pas
TRttiEnumerationType=class(TRttiOrdinalType)
私有的
函数GetMaxValue:Longint;推翻
函数GetMinValue:Longint;推翻
函数getUnderlineType:trttType;
构造函数创建(apapackage:TRttiPackage;AParent:TRttiObject;var P:PByte);推翻
{$OFF}
函数GetNames:TArray;
类函数GetName(AValue:T):字符串;重新引入;静止的
类函数GetValue(const AName:string):T;静止的
{$HINTS ON}
公众的
属性underyingtype:TRttiType read getunderyingtype;
结束;
您的选项包括:
还可以使用类帮助器访问私有类方法
program Project50;
{$APPTYPE CONSOLE}
uses
System.SysUtils,RTTI;
Type
TRttiEnumerationTypeHelper = class helper for TRttiEnumerationType
public
class function Name<T>(AValue: T): string; inline;
class function Value<T>(const AName: string): T; inline;
end;
class function TRttiEnumerationTypeHelper.Name<T>(AValue: T): string;
begin
Result := TRttiEnumerationType.GetName<T>(AValue);
end;
class function TRttiEnumerationTypeHelper.Value<T>(const AName: string): T;
begin
Result := TRttiEnumerationType.GetValue<T>(AName);
end;
Type
TEnum = (teTest1,teTest2,teTest3);
begin
WriteLn( TRttiEnumerationType.Name<TEnum>(teTest1));
WriteLn( Ord(TRttiEnumerationType.Value<TEnum>('teTest1')));
ReadLn;
end.
程序项目50;
{$APPTYPE控制台}
使用
System.SysUtils,RTTI;
类型
TRttiEnumerationTypeHelper=TRttiEnumerationType的类帮助器
公众的
类函数名(AValue:T):字符串;内联;
类函数值(常量名称:字符串):T;内联;
结束;
类函数TRttiEnumerationTypeHelper.Name(AValue:T):字符串;
开始
结果:=TRttiEnumerationType.GetName(AValue);
结束;
类函数TRttiEnumerationTypeHelper.Value(常量名称:字符串):T;
开始
结果:=TRttiEnumerationType.GetValue(AName);
结束;
类型
TEnum=(teTest1,teTest2,teTest3);
开始
WriteLn(trttineumerationtype.Name(teTest1));
WriteLn(Ord(trttineumerationtype.Value('teTest1'));
ReadLn;
结束。
它的缺点是另一个助手可能会隐藏此声明。要使用它,只需将声明放在一个单元中,并在需要的地方包含该单元
如果要获得函数的原始名称,请使用此处介绍的技巧:3。[…]向接口部分添加类型或函数不会强制完全重新编译RTL。重新编译整个RTL的过程是由对RTL.pas单元的更改自动触发的,还是我必须手动执行?我认为最后一个答案是正确的,但我不确定。非常感谢:答案#4是一个我可以接受的解决方法:-)不会自动触发。你真的想避免完全重新编译,因为你的直觉已经告诉你了。选项4是我个人的做法。我认为您不需要为此类操作调用新样式的RTTI。我认为选项4与其说是解决问题的办法,不如说是最好的选择。它有所有班级/记录助手的缺点,但足够简单。@LURD看起来选民更喜欢你的答案而不是我的答案。代码对文字的力量,嗯?很有趣。我考虑过类助手,但不知道可以使用它们访问类函数。Fabio,是的,另一个助手可能会这样做。如果它是一个已知的帮助器,它们可以从一个继承到另一个。这很有趣:必须小心不要在其他单元中声明同一个类帮助器,如果包含这些单元,则可以隐藏此声明。
program Project50;
{$APPTYPE CONSOLE}
uses
System.SysUtils,RTTI;
Type
TRttiEnumerationTypeHelper = class helper for TRttiEnumerationType
public
class function Name<T>(AValue: T): string; inline;
class function Value<T>(const AName: string): T; inline;
end;
class function TRttiEnumerationTypeHelper.Name<T>(AValue: T): string;
begin
Result := TRttiEnumerationType.GetName<T>(AValue);
end;
class function TRttiEnumerationTypeHelper.Value<T>(const AName: string): T;
begin
Result := TRttiEnumerationType.GetValue<T>(AName);
end;
Type
TEnum = (teTest1,teTest2,teTest3);
begin
WriteLn( TRttiEnumerationType.Name<TEnum>(teTest1));
WriteLn( Ord(TRttiEnumerationType.Value<TEnum>('teTest1')));
ReadLn;
end.