繁体   English   中英

将泛型类型的成员转换为TObject?

[英]Cast member of generic type to TObject?

我目前在思考,我想调用一个泛型类的情景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;

不幸的是最后一行没有编译,这并不奇怪,因为类型不匹配。 问题是:我可以编译吗? 我尝试转换为Pointer然后转向TObject但这给了我一个无效的类型转换错误。 有没有办法让FInstance : T成为一个TObject引用,然后我可以传递给Invoke

或者有没有其他方法来实现我想要的? 请注意,重点是获取此类中的所有内容,因此我不想创建只接受对象的TObjectMyClass

谢谢你的帮助。

这不够吗?

if PTypeInfo(TypeInfo(T))^.Kind = tkClass then
  TObject(FInstance).Free;

直接转换为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;

这给我带来了糟糕的设计。 泛型的一个要点就是摆脱像这样的动态类型决策。

如果你真的在使用泛型特性,那么让我更有意义的是让一个带有受约束的类型参数的子类只接受TObject后代。 既然你已经决定你是静态如何去实例化泛型类,它是没有任何麻烦使用TMyObjectClassT是一类,并使用TMyClass别处。

如果单个容器需要同时包含对象和非对象,我想你会被迫采取你正在采取的方法。 但如果情况并非如此,那么我觉得有点不对劲。

实际上,我自己就找到了答案。 TValue.From可以解决问题:

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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM