如何将TObject转换为TObjectList <T>?

nor*_*aul 4 delphi generics rtti delphi-xe7

我有一个过程需要将一个TObjects 数组插入到列表中.该列表可以是任何支持的类型,例如TObjectList,TObjectList<T>,TROArray等.

该过程如下所示:

type
  TObjectArray = Array of TObject;

...

procedure TMyClass.DoAssignObjectList(const ObjectArray: TObjectArray;
  const DstList: TObject);
var
  i: Integer;
begin
  if DstList is TObjectList then
  begin
    for i := 0 to pred(TObjectList(DstList).Count) do
      TObjectList(DstList).Add(ObjectArray[i]);
  end else
  if DstList is TObjectList<T> then // Obviously this doesn't work
  begin
    for i := 0 to pred(TObjectList<T>(DstList).Count) do
      TObjectList<T>(DstList).Add(ObjectArray[i]);
  end
  else
  begin
    raise Exception.CreateFmt(StrNoDoAssignORMObject, [DstList.ClassName]);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

如何检查对象是否为a TObjectList<T>,然后向其中添加数组元素?

Ste*_*nke 5

您必须使用一点RTTI来获取有关泛型类型的更多信息.

下面的代码使用Spring4D,它有一些方法:

uses 
  ...
  Spring.Reflection;

procedure DoAssignObjectList(const ObjectArray: TObjectArray;
  const DstList: TObject);

  function IsGenericTObjectList(const obj: TObject): Boolean;
  var
    t: TRttiType;
  begin
    t := TType.GetType(obj.ClassInfo);
    Result := t.IsGenericType and (t.GetGenericTypeDefinition = 'TObjectList<>');
  end;

begin
  ...
  if IsGenericTObjectList(DstList) then
  begin
    for i := 0 to pred(TObjectList<TObject>(DstList).Count) do
      TObjectList<TObject>(DstList).Add(ObjectArray[i]);
  ...
end;
Run Code Online (Sandbox Code Playgroud)

除此之外,您还可以获取有关列表的通用参数类型的信息,以检查您放入其中的对象是否符合要求(仅适用于通用类型的课程):

function GetGenericTObjectListParameter(const obj: TObject): TClass;
var
  t: TRttiType;
begin
  t := TType.GetType(obj.ClassInfo);
  Result := t.GetGenericArguments[0].AsInstance.MetaclassType;
end;
Run Code Online (Sandbox Code Playgroud)