Delphi 如何发布RTL单元的私有类函数?

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

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 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;
结束;
您的选项包括:

  • 重新编译整个RTL
  • 使用RTTI访问私有方法
  • 向RTTI单元添加一个新类,该单元公开函数。我记得,向接口部分添加类型或函数不会强制完全重新编译RTL
  • 在RTTI单元外部自行实现功能。例如,请在此处查看答案:
  • 如LURD的回答所述,使用班级帮手破解私密处
    还可以使用类帮助器访问私有类方法

    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.