Delphi 如何将通用T转换为TObject?
我有一个方法需要返回一个对象。当然,只有当Delphi 如何将通用T转换为TObject?,delphi,generics,Delphi,Generics,我有一个方法需要返回一个对象。当然,只有当T是一个对象时,它才有意义: function TGrobber<T>.Swipe: TObject; var current: T; begin { If generic T is not an object, then there's nothing we can return But we'll do the caller a favor and not crash horribly.
T
是一个对象时,它才有意义:
function TGrobber<T>.Swipe: TObject;
var
current: T;
begin
{
If generic T is not an object, then there's nothing we can return
But we'll do the caller a favor and not crash horribly.
}
if PTypeInfo(TypeInfo(T))^.Kind <> tkClass then
begin
Result := nil;
Exit;
end;
//We *are* an object, return the object that we are.
current := Self.SwipeT;
Result := TObject(current); <--E2089 invalid class typecast
end;
是的,可以通过TValue完成,但这不是正确的方法。我认为最好让编译器验证它是一个TObject(或后代)
unitgrobberu;
接口
类型
TGrobber=类
公众的
功能滑动:TObject;
结束;
实施
{tgrober}
函数tgrobider.swip:TObject;
开始
结果:=T;
结束;
结束。
然后您可以测试它:
procedure TForm37.FormCreate(Sender: TObject);
var
Grobber1 : TGrobber<TEdit>;
Grobber2 : TGrobber<Integer>; <-- Does not compile
begin
end;
程序TForm37.FormCreate(发送方:TObject);
变量
Grobber1:TGrobber;
Grobber2:TGrobber 我看到两个主要的选择。如果泛型类型必须是类类型,并且在编译时知道这一点,则应该对该类型应用约束:
type
TGrobber<T: class> = class
....
end;
这是可能的,因为编译器对泛型类型强制执行约束。因此知道赋值对所有可能的实例化都有效
我要说的是,泛型类有一个返回TObject
的函数似乎有些奇怪。为什么函数不返回t
如果无法约束,则简单指针类型转换是最干净的方法:
Result := PObject(@current)^;
显然,您需要检查T
是否是一种类类型,您已经演示了对该类的掌握程度
由于Delphi XE7,因此使用System.GetTypeKind
检查类型更为简单:
if GetTypeKind(T) = tkClass then
Result := PObject(@current)^
else
Result := nil;
@我测试了这个概念。代码Result:=TObject(字节(7))代码>编译并运行。这可能是等待中的访问冲突。幸运的是,由于我的先决条件,我不会将字节
强制转换为对象
。可能是TValue.From(current).AsObject
?@TLama哇,TValue
助手记录解决了所有问题。复制/粘贴我为奖励您的声誉而添加到问题中的答案。@Guillem TValue是重量级的,不适合此任务。要么在编译时进行约束,要么使用类似于:Result:=PObject(@current)^
@Guillem TValue有它的位置,它通常作为RTTI方法参数的管道Result:=T
不会编译,因为T
是一个类型而不是实例。此外,不需要截图来显示编译器错误。编译器错误是文本。它们可以简单地一字不差地粘贴为文本。您在@DavidHeffernan中正确地看到了Swipe的返回值a hould of cause be Result:=Swipe。但是它确实编译了。不,它不编译。[dcc32错误]E2010不兼容的类型:“TObject”和“T”那么让我更准确地说:在Delphi Xe中,它确实存在,这是一个编译器错误。我不明白你为什么坚持这样做。TValue
与你的代码做同样的事情(将指针投射到TObject以阻止键入)。虽然to在期间从
计算了一些额外的内容。另一方面,在运行时使用规范的TValue
typing helper记录来查询和操作泛型类型有其优点。@IanBoyd我不相信这就是TValue
的目的。然而,如果你愿意,你显然可以这样做。就我个人而言,我会按照上面写的方式来做,但这两种方式都不会让我感到太激动。而且,我的Delphi版本中不存在GetTypeKind
。我们又来了。是的,它在XE7中似乎是新的。我想你的代码现在胜出了。
type
TGrobber<T: TMyObject> = class
....
end;
Result := current;
Result := PObject(@current)^;
if GetTypeKind(T) = tkClass then
Result := PObject(@current)^
else
Result := nil;