gpt4 book ai didi

delphi - 在类构造函数中完成类注册后,不调用类构造函数

转载 作者:行者123 更新时间:2023-12-03 15:16:39 24 4
gpt4 key购买 nike

我正在编写一个简单的依赖注入(inject)/控制反转系统,该系统基于 TDictionary 保存抽象类引用及其各自的实现类。

我的目标是:

  • 避免按类型直接实例化(显然)。
  • 将类单元包含在 dpr 中应该足以使其注册并可通过 di/ioc 系统进行选择和实例化。
  • 仅在实现部分声明具体的实现类。
  • 使用类构造函数而不是初始化部分。

顺便说一句,我知道使用类构造函数来利用智能链接和希望包含一个单元足以使类可用是相互矛盾的。出于其他原因,我想使用类构造函数而不是初始化部分。我希望将所有类初始化/注册代码保留在一起,而不必将其拆分在类构造函数和初始化部分之间。

问题

我希望在类构造函数中将类注册到工厂中。不幸的是,编译器认为仅在其自己的类构造函数中使用其类型并不会“触及”该类。

当我将注册函数放在初始化部分时,编译器确实认为该类已被触及并调用类​​构造函数。但这违背了我将所有类初始化代码保留在类构造函数中的目的。

两个问题

  • 编译器是否应该考虑在自己的类构造函数中使用该类“接触类”,还是期望编译器这样做太过分了?
  • 有人对我如何在不使用初始化部分的情况下仍然实现我的目标有什么聪明的想法吗?

示例

应用程序中使用的抽象类:

TSite = class abstract (TObject)
function GetURL: string; virtual; abstract;
property URL: string read GetURL;
end;

TSites = class (TList<TSite>);

TThisApplication = class abstract (TObject)
function Sites: TSites; virtual; abstract;
end;

TThisApplication 的具体实现类(在实现部分声明!)

  TThisApplicationConcrete = class(TThisApplication)
class constructor ClassCreate;
strict private
FSites: TSites;
function Sites: TSites; override;
end;

class constructor TThisApplicationConcrete.ClassCreate;
begin
RegisterImplementorClass(TThisApplication, TThisApplicationConcrete);
end;

function TThisApplicationConcrete.Sites: TSites;
var
SiteList: TSites;
begin
if not Assigned(FSites) then begin
SiteList := TSites.Create; // Change to use factory
//RetrieveSites(SiteList);
FSites := SiteList;
end;

Result := FSites;
end;

获取TThisApplication实例的函数:

function ThisApplication: TThisApplication;
var
ImplementorClass: TClass;
begin
ImplementorClass := GetImplementorClass(TThisApplication);
if Assigned(ImplementorClass) then begin
Result := ImplementorClass.Create as TThisApplication;
end else begin
Result := nil;
end;
end;

目前这是在单独的函数中编码的,但可以将其移至工厂。

完整示例代码

如果有人想尝试,我可以在以下位置找到我的测试项目的完整代码:http://www.bjsoftware.com/delphistuff/stackoverdlow/classconstructors.zip

压缩包内容:

  • 4 个项目都使用相同的源文件,仅条件定义不同(这就是 dproj 也包含在内的原因)
  • 4 个源文件
  • groupproj 及其包含所有 4 个项目的 DSK
  • RunTestApps.cmd 用于运行所有 4 个项目
  • Results.txt 包含我运行 RunTestApps.cmd 的输出
  • 包含此问题文本的 WriteUp.txt

请记住,您始终需要执行“构建所有项目”,因为所有 dcu 和 exe 都将转到源目录,否则您将面临很多错误和/或困惑,因为 exe并没有做它的名字所表明的那样。

最佳答案

这符合预期。正如 Uwe 指出的,自引用类构造函数不足以触发包含。将引用放在初始化部分就可以解决问题,因为它位于类本身之外。尝试 self 引用一个类以进行包含就像试图通过拉自己的背带将自己从深坑中拉出来。

关于delphi - 在类构造函数中完成类注册后,不调用类构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6231871/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com