首页 文章

我如何使用Move程序填充TList <T>元素?

提问于
浏览
4

我需要将存储在一个字节数组中的数据移动到位于TList中的一组记录,但是我收到了这个错误

E2197常量对象不能作为var参数传递

此代码重现了该问题 .

uses
  System.Generics.Collections,
  System.SysUtils;

type
  TData = record
    Age : Byte;
    Id  : Integer;
  end;

//this code is only to show the issue, for simplicity i'm filling only the first  
//element of the TList but the real code needs fill N elements from a very big array.  
var
  List : TList<TData>;
  P : array [0..1023] of byte;
begin
  try
    List:=TList<TData>.Create;
    try
      List.Count:=1;
      //here i want to move the content of the P variable to the element 0
      Move(P[0],List[0], SizeOf(TData));

    finally
      List.Free;
    end;

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

我如何将缓冲区的内容复制到TList元素

2 回答

  • 4

    在XE2中, TList<T> 的内部存储是不透明和隐藏的 . 您无法通过正常方式访问它 . 将复制对列表元素的所有访问 - 对底层存储的引用不可用 . 所以你不能使用 Move 来搞定它 . 如果你想要一个可以blit的结构,你应该考虑一个动态数组 TArray<T> .

    您总是可以使用为 TList<TData> 实现类助手的技巧,该助手将公开私有变量 FItems . 这非常hacky但会做你要求的 .

    type
      __TListTData = TList<TData>;
      //defeat E2086 Type 'TList<T>' is not yet completely defined
    
    type
      TListTDataHelper = class helper for TList<TData>
        procedure Blit(const Source; Count: Integer);
      end;
    
    procedure TListTDataHelper.Blit(const Source; Count: Integer);
    begin
      System.Move(Source, Pointer(FItems)^, Count*SizeOf(Self[0]));
    end;
    

    我想你可能想在 TListTDataHelper.Blit 中进行一些参数检查,但我会把它留给你 .

    如果您使用的是XE3,则可以使用List属性访问 TList<T> 的专用存储 .

    Move(P, Pointer(List.List)^, N*SizeOf(List[0]));
    

    如果你不需要blit并且可以使用for循环,那么就这样做:

    type
      PData = ^TData;
    var
      i: Integer;
      Ptr: PData;
    ....
    List.Count := N;
    Ptr := PData(@P);
    for i := 0 to List.Count-1 do
    begin
      List[i] := Ptr^;
      inc(Ptr);
    end;
    

    但我解释你的问题,你希望避免这个选项 .

  • 1

    而不是使用 Move() ,而是尝试使用 TList<T>.Items[] 属性setter,让编译器和RTL为您处理复制:

    type
      PData = ^TData;
      ...
    
    List[0] := PData(@P[0])^;
    

相关问题