Delphi中构造函数约束的用途是什么?

4

标题已经很明确了...

为什么你要使用constructor约束?

这显然已经被class约束隐含了。

如果你只使用它,你无法对你创建的事物做任何操作。

它为什么存在?

额外信息:

请注意,以下代码在添加"constructor"约束之前是无法编译的:

program Project3;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;


type
  TSomeClass<T: class> = class
    function GetType: T;
  end;


{ TSomeClass<T> }

function TSomeClass<T>.GetType: T;
begin
  Result := T.Create;
end;

begin
  try
    { TODO -oUser -cConsole Main : Insert code here }
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

2
它几乎没有用,因为它必须是无参数的。 - David Heffernan
在添加了上述代码之后,我认为类约束应该意味着构造函数约束。 - Nick Hodges
2个回答

8

你为什么需要使用构造函数约束?

这显然已经包含在类约束中了。

并不是这样。构造函数约束要求类型具有公共的无参构造函数,然后允许调用该构造函数。

并非所有类都具有公共的无参构造函数。


1
但是你为什么会在意呢?(我必须说,能够得到不朽的Jon Skeet先生回答我的问题是一种荣幸!) - Nick Hodges
1
@NickHodges 如果类型有构造函数约束,那么你可以写 T.Create。 - Linas
1
@NickHodges:你会关心这个问题,是因为在工厂案例等情况下,你可能想要创建一个新的实例。你关心这个问题,是因为它允许你做一些其他情况下无法做到的事情。 - Jon Skeet
@JonSkeet 如果你知道如何隐藏TObject的默认构造函数(http://andy.jgknet.de/blog/2011/07/hiding-the-tobject-create-constructor/),那么这是有意义的。否则,你总是可以访问它。 - Stefan Glienke
@StefanGlienke:那么我的回答在这里实际上是准确的吗?我绝对不想留下错误的信息...如果您有任何建议的更改,请随意编辑... - Jon Skeet
显示剩余8条评论

2

在我看来,这个限制的官方原因是编译器实际上无法自己处理它。

这只是一个标志,对于编译器来说,它也可以自己设置,因为编译器确实意识到我们需要一个构造函数的限制。所以,它可以被编译器自动处理,因为泛型类将在使用该类之前进行编译。

也许我们会在XE9中得到它。

更新

如果TComponent作为一个没有公共无参数构造函数的类类型被接受,那么构造函数的限制就是无用的,因为这个(Nick的扩展示例)编译并生成了一个TComponent实例。当然,它不会调用原始的构造函数TComponent.Create(AOwner:TComponent),而是调用TObject.Create,但你有一个TComponent实例。

program Project3;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, System.Classes;

type
  TSomeClass<T: class, constructor> = class
    function GetType: T;
  end;

{ TSomeClass<T> }

function TSomeClass<T>.GetType: T;
begin
  Result := T.Create;
end;

var
  SomeClass : TSomeClass<TComponent>;
  Component : TComponent;
begin
  try
    SomeClass := TSomeClass<TComponent>.Create;
    Component := SomeClass.GetType;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

更新

TSomeClass<T: class, constructor>

与...的意思相同

TSomeClass<T: constructor>

因为一个记录可以有一个构造函数,但不能没有参数,所以我们对类有一个隐含的约束。反过来说

TSomeClass<T: class>

可以有一个隐式构造函数约束


实际上,您可能会以部分或未初始化的实例结束。例如,尝试以这种方式创建控件。虽然您无法调用TControl.Create,因为它被构造函数隐藏,该构造函数需要AOwner,但是当给定具有构造函数约束的通用类型时,编译器可以调用它! - Stefan Glienke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接