Delphi 将泛型类型的强制转换成员转换为ToObject?
我目前正在考虑一个场景,在这个场景中,我需要一个泛型类,该类对其项调用Delphi 将泛型类型的强制转换成员转换为ToObject?,delphi,generics,casting,delphi-2010,Delphi,Generics,Casting,Delphi 2010,我目前正在考虑一个场景,在这个场景中,我需要一个泛型类,该类对其项调用Free,如果这些项属于对象类型。因此,我尝试了以下方法: if (PTypeInfo (TypeInfo (T)).Kind = tkClass) then begin RttiType := RttiContext.GetType (TypeInfo (T)); FreeMethod := RttiType.GetMethod ('Free'); if (FreeMethod <> nil) t
Free
,如果这些项属于对象类型。因此,我尝试了以下方法:
if (PTypeInfo (TypeInfo (T)).Kind = tkClass) then
begin
RttiType := RttiContext.GetType (TypeInfo (T));
FreeMethod := RttiType.GetMethod ('Free');
if (FreeMethod <> nil) then
FreeMethod.Invoke (FInstance, []);
end;
if(PTypeInfo(TypeInfo(T)).Kind=tkClass)那么
开始
RttiType:=RttiContext.GetType(TypeInfo(T));
FreeMethod:=RttiType.GetMethod('Free');
如果(方法为零),则
Invoke(FInstance,[]);
结束;
不幸的是,最后一行没有编译,这并不奇怪,因为类型不匹配。问题是:我能让它编译吗?我试图转换到指针
,然后转换到对象
,但这给了我一个无效的类型转换错误。有没有办法将FInstance:T
放入TObject
引用中,然后将其传递给Invoke
或者有没有其他方法来实现我想要的?请注意,整个要点是获取这个类中的所有内容,因此我不想创建一个只获取对象的TObjectMyClass
谢谢你的帮助。事实上,我自己刚刚找到了答案<代码>t值。从执行以下操作:
if (PTypeInfo (TypeInfo (T)).Kind = tkClass) then
begin
RttiType := RttiContext.GetType (TypeInfo (T));
FreeMethod := RttiType.GetMethod ('Free');
if (FreeMethod <> nil) then
FreeMethod.Invoke (TValue.From <T> (FInstance), []);
end;
if(PTypeInfo(TypeInfo(T)).Kind=tkClass)那么
开始
RttiType:=RttiContext.GetType(TypeInfo(T));
FreeMethod:=RttiType.GetMethod('Free');
如果(方法为零),则
调用(TValue.From(FInstance),[]);
结束;
直接转换到TObject在Delphi 2010中似乎有效:
FreeMethod.Invoke (TObject(FInstance), []);
完整示例:
implementation
uses TypInfo, Rtti;
{$R *.dfm}
type
TTest<T> = class
FInstance : T;
procedure F;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
O : TTest<TObject>;
begin
O := TTest<TObject>.Create;
O.FInstance := TStringList.Create;
O.F;
O.Free;
end;
{ TTest<T> }
procedure TTest<T>.F;
var
RttiType : TRttiType;
FreeMethod : TRttiMethod;
RttiContext : TRttiContext;
begin
if (PTypeInfo (TypeInfo (T)).Kind = tkClass) then
begin
RttiType := RttiContext.GetType (TypeInfo (T));
FreeMethod := RttiType.GetMethod ('Free');
if (FreeMethod <> nil) then
FreeMethod.Invoke (TObject(FInstance), []);
end;
end;
实现
使用TypInfo、Rtti;
{$R*.dfm}
类型
TTest=类
结果:T;
程序F;
结束;
过程TForm1.FormCreate(发送方:TObject);
变量
O:测试;
开始
O:=TTest.Create;
O.FInstance:=TStringList.Create;
O.F;
O.免费;
结束;
{TTest}
程序测试F;
变量
rttType:trtType;
自由法:trtti法;
RttiContext:TRttiContext;
开始
如果(PTypeInfo(TypeInfo(T)).Kind=tkClass),那么
开始
RttiType:=RttiContext.GetType(TypeInfo(T));
FreeMethod:=RttiType.GetMethod('Free');
如果(方法为零),则
Invoke(TObject(FInstance),[]);
结束;
结束;
对我来说,这有点糟糕的设计。泛型的要点之一是避免这样的动态类型决策
如果您真的在使用泛型特性,那么对我来说,使用一个带有类型参数的子类会更有意义,该类型参数受约束为take onlyTObject
子类。因为您必须静态地决定如何实例化泛型类,所以当T
是一个类时,使用TMyObjectClass
并在其他地方使用TMyClass
并没有任何问题
我想如果一个容器需要同时包含对象和非对象,那么您将被迫采取您正在采取的方法。但如果不是这样的话,我就会觉得有些不对劲。这还不够吗
if PTypeInfo(TypeInfo(T))^.Kind = tkClass then
TObject(FInstance).Free;
:谢谢你!哈哈……我应该先试试那个显而易见的解决办法。我假设它会失败,所以我尝试先转换为
指针
,但这不起作用…很抱歉:-/Delphi 2010不喜欢将类型限制为仅TObject
。这不会编译:typetsomethingeneric
,而会编译:typetsomethingeneric
@Cosmin您这样写:tsomethingeneric
,正如我在问题中所说的:我不想要只处理对象的子类。这是唯一需要特殊情况的地方。其他一切都与类型无关。它是!我只是想将RTTI部分移到构造函数中,但我想请求类型信息并不太昂贵。但是你是对的,整个RttiMethod
方法可能是不必要的。谢谢和+1