【问题标题】:why i can't declare a generic form为什么我不能声明一个通用形式
【发布时间】:2015-02-02 14:09:18
【问题描述】:

我想要做的基本上是声明一个这样的表单:

TFormCRUDBase<T : class> = class(TFormLayoutBase, MVP.Intf.CRUD.ICRUDView<T>)
{ ... }
end;

无论是否允许此功能,编译器都不会指责任何错误或警告消息,但是当我尝试在设计器中添加一些控件时,我会收到此消息

Declaration of class TFormCRUDBase is missing or incorrect.

所以问题是为什么语法允许我使用,而 IDE 只是把我踢开。

提前谢谢

【问题讨论】:

  • 类的声明必须关闭是end关键字。
  • 可能我不是很清楚,类中添加了更多的东西,比如字段和方法,我只是把它声明在这里。我进行了修改,以便更清晰。
  • 正如戴维斯所说:表单设计器不支持泛型类型。但是你可以通过让你的 Form 继承一个非泛型类来做一个 wotk arround。如果您愿意,我可以为您提供解决方案
  • @JensBorrisholt 是的,你能详细说明一下吗?

标签: delphi delphi-xe2


【解决方案1】:

简单地说,表单设计器不支持泛型类型。

编译器适用于泛型类型。您可以使用运行时代码构建 UI、添加控件等。但是表单设计器不支持泛型类型。

【讨论】:

  • 天哪,这太令人沮丧了,有时我真的看不懂delphi。为什么他们在语法上提供了这样的功能,但不处理需要在 IDE 中进行的更改才能兼容这样的功能。
  • 好吧,我猜设计师认为TForm后代不是使用泛型的主要候选者。这可能是合理的。我想,让 .dfm 文件支持通用性会涉及到相当多的工作。我认为设计师权衡了利弊,并决定在其他地方投入精力。让你感到沮丧。
  • 我同意他们决定将精力放在其他地方的事实,我完全不同意编译器 x IDE 之间的差异,我的意思是,在这种情况下,IDE 应该警告我这是'不允许或不支持,并且不抛出一些模糊的通用异常。所以最后我有一个编译器说一切都很好,另一方面 IDE 说它不是。
  • @kabstergo - “开发人员不需要时使用”很可能是不正确的。专业软件开发不是随随便便的开发人员一时兴起而发生的。在这种情况下,我怀疑没有多少客户要求在 IDE 设计器中支持表单中的泛型...
  • @kabstergo:与其说是“方便”(暗示懒惰),还不如说是“实施这个并不值得,因为它可能需要很多时间和/或几乎没有任何要求”。换句话说,不做所有可能的事情,而只做有意义的事情,通常是一个可靠的商业决策。想想 YAGNI。
【解决方案2】:

您要求工作。解决方案很简单,但并不优雅。你必须在强类型类上做,并让你从中受到启发。

首先我制作了一些虚拟类型:

type
  ICRUDView<T> = Interface
   function GetObject : T;
  end;

  TMyObject = class
    function Time: String;
  end;

和一个简单的实现:

{ TMyObject }

function TMyObject.Time: String;
begin
  Result := TimeToStr(now);
end;

procedure TForm5.FormCreate(Sender: TObject);
begin
  Caption := Self.GetObject.Time;
end;

然后是你必须继承的强类型:

type
  TMyClassForm = class(TForm, ICRUDView<TMyObject>)
  strict private
    InternalObject: TMyObject;
  public
    function GetObject: TMyObject;
  end;

及其实现:

{ TMyClassForm }

function TMyClassForm.GetObject: TMyObject;
begin
  if (InternalObject = nil) then
    InternalObject := TMyObject.Create;

  Result := InternalObject;
end;

最后你让你的表单从你新创建的类中继承:

  TForm5 = class(TMyClassForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

并在您的表单中使用它

procedure TForm5.FormCreate(Sender: TObject);
begin
  Caption := Self.GetObject.Time;
end;

它正在工作,但它并不优雅!

【讨论】:

    猜你喜欢
    • 2022-12-13
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多