【问题标题】:Generic helper classes in DelphiDelphi 中的通用助手类
【发布时间】:2018-08-25 18:50:41
【问题描述】:

我有一对类 A 和 B,它们必须相互引用。也就是说A的接口使用子句必须提到B的单位,B的接口使用子句必须提到A的单位。这在Delphi中是循环引用,不允许。我正在使用here 找到的方法来解决循环问题。基本上,A 对 B 的引用按预期存在,但 B 对 A 的引用被降级为 TObject 引用,并且 B 使用帮助器类将对 A 的引用转换为正确的类型。这里有代码sn-ps来说明:

unit A;

interface

uses
    B;

type
    TA = class(TObject)
    public
        Name: string;
        B: TB;
    end;

implementation

end.

unit B;

interface

type
    TB = class(TObject)
    public
        Name: string;
    protected
        fA: TObject;
    end;

implementation

end.

unit BHelper;

interface

uses
    A,
    B;

type
    TBHelper = class helper for TB
    private
        function GetA: TA;
        procedure SetA(Value: TA);
    public
        property A: TA read GetA write SetA;
    end;

implementation

function TBHelper.GetA: TA;
begin
    Result := TA(fA);
end;

procedure TBHelper.SetA(Value: TA);
begin
    fA := a;
end;

end.

我实际上有几对这样的课程。这是很多帮助类,它们都在做同样的事情。所以我尝试编写一个通用的帮助类,可以通过参数化来帮助像 B 这样的类:

unit GenericHelper;

interface

uses
    A,
    B;

type
    TGenericHelper<T1, T2> = class helper for T2  //Error: Type parameters not allowed
    private
        function GetA: T1;
        procedure SetA(Value: T1);
    public
        property A: T1 read GetA write SetA;
    end;

implementation

function TGenericHelper<T1, T2>.GetA: T1;
begin
    Result := T1(fA);  //Error: undeclared parameter fA
end;

procedure TGenericHelper<T1, T2>.SetA(Value: T1);
begin
    fA := a;  //Error: undeclared parameter fA
end;

end.

我的问题是我对泛型类的了解不够,无法知道这是否可行。我不知道如何解决代码中显示的错误。

有没有办法做到这一点?

完全披露:情况实际上比这更丰富。这些对排列在 A-B-C-D 等层次结构中,其中 A 持有对 B 的引用,B 持有对 A 和 C 的引用,C 持有对 B 和 D 的引用,D 持有对 C 的引用。这些是一对多的其中 A 实际上持有 B 的列表,每个 B 持有 C 的列表,每个 C 持有 D 的列表。理想的解决方案不会排除这些关系。我也更喜欢每个单元一个类,而不是将相关的类组合成一个单元。

谢谢

【问题讨论】:

  • TFriend 的声明在哪里? fChildTFriend 的成员吗? fParent?看起来您已经使用与实际类型名称冲突的泛型类型名称声明了泛型(即:与实际类型名称相同并且正在隐藏)。您究竟想在这里完成什么?
  • 为了清楚起见,我已经重写了这个问题。
  • 为什么不把 A/B 放在同一个单元中并使用前向声明?

标签: delphi generics helper


【解决方案1】:

这个错误很明显

 TGenericHelper<T1, T2> = class helper for T2  //Error: Type parameters not allowed

你不能像这样使用泛型。原因应该很明显,因为您的实现在实例化泛型类之前尝试访问属于特定类的变量(使实现非泛型)。

最简单的做法是将 A/B(和 C/D 等)放在一个单元中,并简单地对类使用前向声明。

unit ABCD;

interface

    TB = class;
    TC = class;
    TD = class;

    TA = class(TObject)
      public
        B: TB;
        C: TC;
    end;

    TB = class(TObject)
       public
         A: TA;
    end;

    TC = class(TObject)
      public
        B : TB;
        D : TD;
    end;

    TD = class(TObject)
      public
        A: TA;
        C: TC;
    end;

implementation

end.

【讨论】:

  • 谢谢。我已经这样做了,但它使文件变得难以管理或令人困惑(对我来说),即使我用 inc 文件将它们切碎。我应该在我的披露说明中提到这一点。
  • 这取决于你是否希望你的代码编译我猜@David
  • @DavidU 好吧,这似乎是一个单独的问题,有一个单独的答案。您当前问题(“我可以用泛型做这个”)的答案是否定的。如果上述解决方案的唯一问题是源文件的大小使您感到困扰,那么您可以使用其他策略来解决该特定问题。
  • 好吧,我的方法显然是错误的。但我并没有把这个或回应当作没有泛型解决方案。既然你这么说,那我就接受答案了。
猜你喜欢
  • 2013-06-19
  • 1970-01-01
  • 1970-01-01
  • 2021-01-04
  • 1970-01-01
  • 1970-01-01
  • 2017-06-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多