Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 将泛型类型的强制转换成员转换为ToObject?_Delphi_Generics_Casting_Delphi 2010 - Fatal编程技术网

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 only
TObject
子类。因为您必须静态地决定如何实例化泛型类,所以当
T
是一个类时,使用
TMyObjectClass
并在其他地方使用
TMyClass
并没有任何问题

我想如果一个容器需要同时包含对象和非对象,那么您将被迫采取您正在采取的方法。但如果不是这样的话,我就会觉得有些不对劲。

这还不够吗

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

:谢谢你!哈哈……我应该先试试那个显而易见的解决办法。我假设它会失败,所以我尝试先转换为
指针
,但这不起作用…很抱歉:-/Delphi 2010不喜欢将类型限制为仅
TObject
。这不会编译:
typetsomethingeneric
,而会编译:
typetsomethingeneric
@Cosmin您这样写:
tsomethingeneric
,正如我在问题中所说的:我不想要只处理对象的子类。这是唯一需要特殊情况的地方。其他一切都与类型无关。它是!我只是想将RTTI部分移到构造函数中,但我想请求类型信息并不太昂贵。但是你是对的,整个
RttiMethod
方法可能是不必要的。谢谢和+1