通用类的类助手?

2024-01-04

我正在使用 Delphi 2009。是否可以为通用类(即 TQueue )编写一个类帮助器。显而易见的

TQueueHelper <T> = class helper of TQueue <T>
  ...
end;

不起作用,也不

TQueueHelper = class helper of TQueue
  ...
end;

我目前仍在使用 Delphi 2009,因此我想添加一些其他方法来扩展泛型类。这些在 Delphi 的新版本中应该同样有效。让我们看看添加一个会是什么样子ToArrayList 类的方法。

拦截器

拦截器类是与其继承的类同名的类:

TList<T> = class(Generics.Collections.TList<T>)
public
  type
    TDynArray = array of T;
  function ToArray: TDynArray;
end;

function TList<T>.ToArray: TDynArray;
var
  I: Integer;
begin
  SetLength(Result, self.Count);
  for I := 0 to Self.Count - 1 do
  begin
    Result[I] := Self[I];
  end;
end;

请注意,您需要使用完全限定名称,Generics.Collections.TList<T>作为祖先。否则你会得到E2086 Type '%s' is not completely defined.

这种技术的优点是您的扩展大部分是透明的。您可以在使用原始 TList 的任何地方使用新 TList 的实例。

这种技术有两个缺点:

  • 如果其他开发人员不知道您重新定义了熟悉的类,则可能会造成混乱。
  • 它不能用于密封类。

通过仔细的单元命名并避免在与拦截器类相同的位置使用“原始”类,可​​以减轻这种混乱。在 Embarcadero 提供的 rtl/vcl 类中,密封类并不是什么大问题。我在整个源代码树中只找到了两个密封类:TGCHandleList(仅在现已不存在的Delphi.NET中使用)和TCharacter。不过,您可能会遇到第三方库的问题。

装饰器模式

装饰器模式允许您通过用继承其公共接口的另一个类包装它来动态扩展一个类:

TArrayDecorator<T> = class abstract(TList<T>)
public
  type
    TDynArray = array of T;
  function ToArray: TDynArray; virtual; abstract;
end;

TArrayList<T> = class(TArrayDecorator<T>)
private
  FList: TList<T>;
public
  constructor Create(List: TList<T>);
  function ToArray: TListDecorator<T>.TDynArray; override;
end;

function TMyList<T>.ToArray: TListDecorator<T>.TDynArray;
var
  I: Integer;
begin
  SetLength(Result, self.Count);
  for I := 0 to Self.Count - 1 do
  begin
    Result[I] := FList[I];
  end;
end;

再次有优点和缺点。

优点

  • 您可以推迟引入新功能,直到实际需要时再引入。需要将列表转储到数组中?构造一个新的 TArrayList,将任何 TList 或后代作为构造函数中的参数传递。完成后只需丢弃 TArrayList。
  • 您可以创建额外的装饰器来添加更多功能并以不同的方式组合装饰器。您甚至可以使用它来模拟多重继承,尽管接口仍然更容易。

缺点

  • 理解起来有点复杂。
  • 将多个装饰器应用于一个对象可能会导致冗长的构造函数链。
  • 与拦截器一样,您无法扩展密封类。

边注

所以看来,如果你想让一个类几乎不可能扩展,就让它成为一个密封的泛型类。那么类助手就无法触及它,也无法继承它。剩下的唯一选择就是包装它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通用类的类助手? 的相关文章

随机推荐

  • 将 HTML 表单提交为 PDF

    我们有一个高分辨率的 PDF 用于打印 其中包含一些表单字段 我们想要一个提交到 PDF 的 HTML 表单 然后将其放入相应的字段中 我在google上找到了解决方案 http koivi com fill pdf form fields
  • jQuery.on();与 JavaScript .addEventListener(); 比较

    有人可以解释一下为什么事件处理程序的执行顺序会根据它们的附加方式而有所不同吗 在下面的示例中我使用的是 on and addEventListener 方法来处理不同的特定事件DOM元素 jsfiddle http jsfiddle net
  • 我可以在屏幕上移动 pygame 游戏窗口吗(pygame)

    在我正在制作的游戏中 我试图在屏幕上移动窗口以进行迷你游戏 不要问 并且我尝试了我看到自己的线程 但只发现了 1 x 100 y 0 import os os environ SDL VIDEO WINDOW POS d d x y imp
  • Android-Libgdx,在游戏开始后单击按钮调用另一个活动

    当游戏开始后单击按钮时我需要调用另一个活动时 我遇到了一个主要问题 游戏是通过Android应用程序接口的initial game 方法调用的 在正常的 Activity 中 我可以轻松地调用另一个 Activity 但从实现 Androi
  • Git:删除损坏的存储

    我有一个破损的储藏室 git stash drop fatal log for refs stash is empty cat git logs refs stash 它确实出现在git log all 尽管 lal f32cdce HEA
  • 从 Silverlight 客户端添加自定义 SOAP 标头

    我正在尝试在 Silverlight 客户端和 Java 服务器之间设置 Web 服务 我需要从 Silverlight 客户端发送用户名令牌 用户名 密码 以进行身份 验证 由于这是一个概念验证 我想让事情变得简单并使用 HTTP 作为我
  • 如何修复错误无法修改标头信息 - 标头已由[重复]发送

    这个问题在这里已经有答案了 我在 codeigniter 中遇到以下类型的错误 我无法解决它 任何人都知道此错误的原因是什么 A PHP Error was encountered Severity Warning Message Cann
  • 我们如何指导屏幕阅读器正确地强调/强调/发音单词

    我正在寻求改善新闻网站上的屏幕阅读器体验 具体来说 我在 Mac 上通过 VoiceOver 进行测试 遇到了以下问题 采取以下句子 直播 发生有新闻价值的事件 在这里 我们希望 LIVE 与 alive l v 但 VoiceOver 将
  • 检索解决方案的路径?

    我们目前正在为我们的公司设置 Team Build 2010 我正在尝试使用工作流活动来检索当前正在构建的解决方案的确切本地路径 我还没有找到获得这个值的方法 有人知道如何 不编写自定义活动 吗 服务器或本地路径之一就足够了 即 TeamP
  • 可以避免在 Java 中默认调用 super() 吗?

    假设由于某种原因我不想隐式调用super 这是默认完成的 class Animal public Animal System out println Constructing an animal class Dog extends Anim
  • 在 python 中使用 oauth2 服务帐户向 Google API 进行身份验证

    我已按照以下说明进行操作https developers google com accounts docs OAuth2ServiceAccount https developers google com accounts docs OAu
  • EntityManager 在 JBoss JSF bean 中的 merge() 上抛出 TransactionRequiredException

    我在 JBoss 5 0 1GA 上设置了一个 JSF 应用程序 以在表中显示用户列表 并允许通过每个用户旁边的按钮删除单个用户 当deleteUser被调用时 调用被传递到一个UserDAOBean 它获取从JBoss注入的EntityM
  • 詹金斯订书机请求失败,没有有效的面包屑

    我正在开发一个 Jenkins 插件 现在我陷入了一个困境 我试图使用 JavaScript 代理获取方法的返回值 如下所述here https wiki jenkins io display JENKINS AJAX with JavaS
  • 带有 LDAP 身份验证的 OWIN

    这是我的场景 我有一个使用 Owin 作为身份验证机制的 MVC 5 应用程序 默认模板在登录操作中调用 SignInManager PasswordSignInAsync 我想覆盖该操作以使用 LDAP 验证用户 而不是查看数据库 我可以
  • 如何同步一系列 Promise?

    我有一个 Promise 对象数组 必须按照它们在数组中列出的顺序来解析 即在前一个元素被解析之前我们不能尝试解析一个元素 作为方法Promise all does 如果一个元素被拒绝 我需要链立即拒绝 而不尝试解析下一个元素 我该如何实现
  • 编写 Spark 作业时是否有理由不使用 SparkContext.getOrCreate?

    我正在编写与 Datastax 中的 Cassandra 对话的 Spark 作业 有时 在执行 Spark 作业中的一系列步骤时 获取新 RDD 比加入旧 RDD 更容易 您可以通过调用来做到这一点SparkContext getOrCr
  • 在 MATLAB 中显示梯度图像的颤动图

    我有一个形象 我想显示使用 MATLAB 中的梯度函数获得的梯度图像的颤动图 最好叠加在梯度图像上 I imread image png gx gy gradient double rgb2gray I g abs gx abs gy fi
  • 具有安全用户身份验证和注册第三方应用程序的简单 PHP REST 服务器

    我正在考虑编写一个 PHP REST API 允许注册用户与第三方应用程序的 Web 服务进行交互 我需要 API 能够做的是 提供对安全用户身份验证的支持 允许注册用户与第三方应用程序的服务交互 该应用程序应事先在系统上注册并获得批准 类
  • 考虑重复,在数组中存储随机值

    这是一个新版本这个帖子 https stackoverflow com questions 4990164 estimating the probability of 3 people sharing a birthday为了将编程问题与概
  • 通用类的类助手?

    我正在使用 Delphi 2009 是否可以为通用类 即 TQueue 编写一个类帮助器 显而易见的 TQueueHelper