标签: class-helpers

如何使用类助手访问类的严格私有成员?

这是一个后续问题:如何隐藏对象的受保护过程?
(我对整个班助手概念有点模糊)

假设我有一个类:

type 
TShy = class(TObject) 
strict private
  procedure TopSecret;
private
  procedure DirtyLaundry;  
protected 
  procedure ResistantToChange;
end; 
Run Code Online (Sandbox Code Playgroud)

我知道如果我通过在同一单元中添加一个后代类来获得源代码,我可以访问私有方法.

我有两个问题:
- 如何使用班助手访问strict private会员?
- 我可以在一个单独的单元中使用类助手来访问(严格)私有成员吗?

delphi class-helpers

28
推荐指数
2
解决办法
6028
查看次数

访问Delphi类的严格受保护属性?

我需要访问一个严格的受保护属性,因为我需要创建一个验证(基于此属性的值)以避免错误.(我没有具有此属性的第三方类的源代码)只有我有类(接口)和dcu的定义(所以我无法更改属性可见性).问题是存在一种访问严格受保护财产的方法吗?(我真正读懂了Hallvard Vassbotn博客,但我不觉得这个特定主题参选.)

delphi class-helpers delphi-xe

16
推荐指数
2
解决办法
4217
查看次数

是否可以为字符串类型使用两个记录助手?

我创建了这个帮助器,以便为该string类型添加更多功能:

type
  AStringHelper = record helper for string
    function Invert: string; overload;
    function InvertMe: string; overload;
  end;
Run Code Online (Sandbox Code Playgroud)

但是当我在我的代码中使用它时,TStringHelperin System.StrUtils"out out"并且我无法使用它的函数.

它们可能共存吗?

delphi class-helpers

11
推荐指数
2
解决办法
3163
查看次数

是否应该使用类助手来开发新代码?

Delphi 8引入了类助手,用于将VCL/RTL映射到.NET对象层次结构.它们允许将方法注入到现有类中,而不会覆盖类或修改原始类.后来的Delphi版本发现了类帮助程序的改进,并将它们移植到Win32.

在帮助中,它说:"在开发新代码时,不应将它们视为一种设计工具."

班级助手违反了传统的OOP,但我认为这不会使他们成为一件坏事.这个警告是否合理?

在开发新代码时是否应该使用类助手?

在开发新代码时是否使用它们?

为什么或者为什么不?

Per Malcolm的评论:新代码意味着每日应用程序开发,你有一些第三方库,一些现有代码,然后是你正在编写的代码.

delphi oop class-helpers

10
推荐指数
3
解决办法
1052
查看次数

如何从Delphi 10.1 Berlin中的类助手访问私有字段?

我想使用Gabriel Corneanu的jpegex,jpeg.TJPEGImage的类助手.阅读这个这个,我了解到,超过德尔福西雅图你不能访问私有字段不再像jpegex确实(在下面的例子中FDATA).和David Heffernan提出的VMT一样,远远超出我的范围.有没有更简单的方法来完成这项工作?

   type
  // helper to access TJPEGData fields
  TJPEGDataHelper = class helper for TJPEGData
    function  Data: TCustomMemoryStream; inline;
    procedure SetData(D: TCustomMemoryStream);
    procedure SetSize(W,H: integer);
  end;

// TJPEGDataHelper
function TJPEGDataHelper.Data: TCustomMemoryStream;
begin
  Result := self.FData;
end;
Run Code Online (Sandbox Code Playgroud)

delphi class-helpers delphi-10.1-berlin

10
推荐指数
3
解决办法
4221
查看次数

泛级类的助手?

我正在使用Delphi 2009.是否可以为泛型类编写一个类助手,即用于TQueue.显而易见的

TQueueHelper <T> = class helper of TQueue <T>
  ...
end;
Run Code Online (Sandbox Code Playgroud)

不起作用,也不起作用

TQueueHelper = class helper of TQueue
  ...
end;
Run Code Online (Sandbox Code Playgroud)

delphi generics delphi-2009 class-helpers

8
推荐指数
3
解决办法
4303
查看次数

在类帮助器语法中``祖先列表'的目的是什么?哪里有记录?有没有用法示例?

所有文档版本(包括最新版本)都提供以下类/记录帮助程序语法:

type
   identifierName = class|record helper [(ancestor list)] for TypeIdentifierName
     memberList
   end;
Run Code Online (Sandbox Code Playgroud)

它只解释了什么......

祖先列表是可选的.它只能为类助手指定.

......并且不再进入可怕的细节.其余文档主题中的用法示例仅仅是利用ancestor list可选的事实.我见过的所有EMBA代码以及所有第三方代码都没有使用这一ancestor list部分.

所以,我的问题在标题中列出:

  • ancestor list类助手语法的目的是什么?
  • 哪里有记录?
  • 有没有用法示例?

delphi class-helpers

7
推荐指数
1
解决办法
539
查看次数

Delphi Class Helper RTTI GetMethod

让我们说我有一个示例类助手

TSampleClassHelper = class helper for TSampleClass
public
  procedure SomeHelper;
end;
Run Code Online (Sandbox Code Playgroud)

我做以下事情:

var
  obj :TSampleClass;
begin
  obj:=TSampleClass.Create;
  obj.SomeHelper;
end;
Run Code Online (Sandbox Code Playgroud)

这按预期工作.

但是,如何使用RTTI来调用辅助方法呢?以下似乎不起作用,GetMethod返回nil.

var
  obj :TSampleClass;
  ctx :TRTTIContext;
  rtype :TRTTIType;
  rmethod :TRTTIMethod;
begin
  obj:=TSampleClass.Create;
  rtype:=ctx.GetType(obj.ClassType);
  rmethod:=rtype.GetMethod('SomeHelper'); // rmethod is nil !
end;
Run Code Online (Sandbox Code Playgroud)

那么RTTI不适用于类助手中定义的方法吗?有没有办法解决?

谢谢.

delphi rtti class-helpers

6
推荐指数
1
解决办法
1787
查看次数

使用RTTI在运行时在Delphi中查找所有类助手?

Delphi 2010中的扩展RTTI是否提供了在运行时列出已定义的类和记录助手的方法

据我所知,当为一个类定义了多个类助手时,Delphi 没有显示提示或警告,在"质量保证"中,类助手检测可能是一个有用的例程.

ps当然我知道我永远不应该使用没有源代码的第三方组件或库,这将使grep类助手变得容易.

delphi rtti class-helpers delphi-2010

5
推荐指数
1
解决办法
1189
查看次数

有没有办法知道在类助手中是否正在创建或销毁对象?

我有很少的类助手用于创建子组件,如弹出菜单,以便在运行时访问这些子组件,我创建了一个Singleton TDictionary.

我的问题是如何知道所有者组件被销毁以从TDictionary中删除子组件?

如果它是一个专门的组件,我将它添加到析构函数中,但我不能在类助手中添加构造函数和/或析构函数.

编辑 - 解决方案

我创建了一个接受TObject作为参数的基础对象,使用时,必须手动完成删除操作.

然后我从它继承了一个新类,重写方法只接受TComponent.这就是现在代码的相关部分:

type     
  TCustomLinkedComponents = class(TCustomLinkedObjects)
  strict private
    type
      TCollector = class(TComponent)
      protected
        procedure Notification(AComponent: TComponent; Operation: TOperation); override;
      end;
  strict private
    FCollector: TCollector;
[..]
  end;

procedure TCustomLinkedComponents.Add(Owner: TComponent; const LinkedName: string; LinkedComponent: TComponent);
begin
  inherited Add(Owner, LinkedName, LinkedComponent);
  FCollector.FreeNotification(LinkedComponent);
end;

procedure TCustomLinkedComponents.TCollector.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited;
  if Operation = opRemove then
    LinkedObjects.Remove(TObject(AComponent));
end;
Run Code Online (Sandbox Code Playgroud)

使用这种方法,我可以解决我的实际需要,并打开后可以轻松扩展.

delphi lifecycle class-helpers

5
推荐指数
1
解决办法
821
查看次数

如何在文字上使用TExtendedHelper?

System.SysUtils.TShortIntHelper(和其他人)我可以写:

output := 5.ToString();
Run Code Online (Sandbox Code Playgroud)

将数字格式化5string.同样,有System.SysUtls.TExtendedHelper,但我无法编译:

output := (5.0).ToString();
Run Code Online (Sandbox Code Playgroud)

E2018:需要记录,对象或类类型

其他不起作用的版本:

  • 5.0.ToString()
  • (1.0+5.1).toString()
  • (5+0.).toString() (说E2029:')'预期但'''找到了)

实际工作的版本:

  • (1+5.1).toString()
  • (1.1+1+5.1).toString()
  • 5.9e0.toString()

如果声明了扩展值const,它也不起作用:

function TestFormat(): String;
const
  q = 5.5;
begin
  Result := q.ToString();
end;
Run Code Online (Sandbox Code Playgroud)

但它的定义是q : extended = 5.5;有效的.所以,我想知道为什么编译器会以这种方式运行.

delphi class-helpers delphi-10.1-berlin

5
推荐指数
1
解决办法
121
查看次数

如何使用类的地址和变量的偏移量来访问类var的值?

我需要使用他的实例和变量的偏移来访问严格私有类var值.

到目前为止尝试了这个,检查这个示例类

type
  TFoo=class
   strict private class var Foo: Integer;
   public
   constructor Create;
  end;

constructor TFoo.Create;
begin
  inherited;
  Foo:=666;
end;

//this function works only if I declare the foo var as 
//strict private var Foo: Integer;
function GetFooValue(const AClass: TFoo): Integer;
begin
  Result := PInteger(PByte(AClass) + 4)^
end;
Run Code Online (Sandbox Code Playgroud)

如您所见,函数GetFooValue仅在foo变量未声明为类var时才起作用.

问题是我必须如何修改 GetFooValue才能获得Foo声明时的值strict private class var Foo: Integer;

delphi pointers class-helpers delphi-xe

4
推荐指数
1
解决办法
816
查看次数

如何使用类助手调用受​​保护的方法?

假设我们有一个方法的类可能非常有用,但是由于受保护范围不可用:

unit Sealed;

interface

type
  TGeneral = class(TObject)
    { this method is useful, but not available }
    protected procedure Useful; virtual;
  end;

  TSpecific1 = class(TGeneral)
    { some descendants override `Useful` method }
    protected procedure Useful; override;
  end;

  TSpecific2 = class(TGeneral)
    { and some dont, but inherit `Useful`ness from the parent }
  end;
Run Code Online (Sandbox Code Playgroud)

我知道有两种老派的方式来接触这种方法,两者都涉及继承和类型转换.两种方法都应该与基本情况#1和高级多态情形#2相同.

program CallingSite;

uses Sealed;

function GetInstance: TGeneral;
begin
  { !PSEUDO! makes compiler happy about the rest of code }
  // depending on use case supposed to return …
Run Code Online (Sandbox Code Playgroud)

delphi oop class-helpers

3
推荐指数
1
解决办法
2492
查看次数