xe2的泛型,试验代码如下:type
  TMyRecI = record
    s:string;
    a:Integer;
  end;
  TMyListI = TList<TMyRecI>;  TMyRecII = record
    str:string;
    b:Integer;
  end;  TMyRecIII = record
    rII:TMyRecII;
    rI:TMyListI;
  end;
  TMyListIII = TList<TMyRecIII>;  //...........
var
  aRecII:TMyRecII;
begin
  aRecII.str:='work';
  aRecII.b:=100;  if (FListIII <> nil) and (FListIII.Count > 0) then
  begin
    FListIII[0].rII:=aRecII;
  end;
end;
 FListIII[0].rII:=aRecII;这个产生编译错误:delphi e2064 left side cannot be assigned to如果省了TMyRecII这个结构
也就是TMyRecIII这样定义:
  TMyRecIII = record
    //rII:TMyRecII;
    str:string;
    b:Integer;
    rI:TMyListI;
  end;FListIII[0].str:='ooo';
这样没问题,这是为什么?(实际项目中这个TRecII有10多个参数,不能省了)

解决方案 »

  1.   

    你是概念乱了, 学习一下数组赋值, 还有数组指针的知识就好了if (FListIII <> nil) and (FListIII.Count > 0) then
      begin
        FListIII[0].rII.str:=aRecII.str;
        FListIII[0].rII.b:=aRecII.b;
      end;
      

  2.   

    FListIII=?????
    and Created??
    and 
    TMyRecIII = record
        rII:TMyRecII;
        rI:TMyListI;
      end;
    TMyRecIII with Type inside, 
    FListIII[0].rII:=aRecII;
    aRecII with String inside.
      

  3.   

    还是建议LZ听1楼的,补补课。
    record 是值类型的,区别于引用类型的class,rocord传递是按值复制的而非复制引用,
    这是本质上区别, record1 := record2 是不能通过编译的。你的 FListIII 是怎么定义和创建的先?
    太晚了,先呼呼
      

  4.   

    唉,楼上的几位兄弟,给出自己的结论前,至少也得试下啊,特别是4楼的兄弟,你说的这话会笑人哟。这个record1 := record2不能编译!!!!简化了无关的代码,变成这样:unit Unit1;interfaceuses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Generics.Collections;type
      TMyRec1 = record
        a:Integer;
        b:Double;
      end;
      TMyList1 = TList<TMyRec1>;  TMyRec3 = record
        a:Integer;
        b:Double;
      end;  TMyRec4 = record
        a:Integer;
        b:Double;
      end;
      TMyList4 = TList<TMyRec4>;
    type
      TForm1 = class(TForm)
        btn1: TButton;
        btn2: TButton;
        lst1: TListBox;
        lbl1: TLabel;
        lbl2: TLabel;
        lbl3: TLabel;
        lbl4: TLabel;
        btn3: TButton;
        procedure btn2Click(Sender: TObject);
      private
        { Private declarations }  public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}
    procedure TForm1.btn2Click(Sender: TObject);
    var
      aRec4,mm:TMyRec4;
      aList4:TMyList4;
      i:Integer;
    begin  aList4:=TMyList4.Create;
      for i := 0 to 4 do
      begin
        aRec4.a:=i;
        aRec4.b:=i;    aList4.Add(aRec4);
      end;  aList4[0].a:=100;
      aList4[0].b:=100;
      //mm:=aRec4;
    end;end.
    //mm:=aRec4是为了4楼兄弟加上的
      

  5.   

     废话不说了,下面这个赋值竟然能不过!!! 
    aList4[0].a:=100;
    aList4[0].b:=100;有人知道这是为什么啊(要下XE2下试通过的)
      

  6.   

    坑啊,delphi TList<T>没有实现:=这个操作符重载,Builder C++里倒是可以自己实现,唉...
    要替换TList<T>里的某个元素,难道要这样:
    Delete(AIndex);
    Insert(AIndex,T);
    这也太丑陋了吧!!!!
      

  7.   


    按着你的思路写了个测试代码, XE测试通过, 不知能否解决你的问题
    ------------------------------------------------------------
    ps: 
      1, 结构体是可以不主动申请空间, 也不做初始化的, 如果嵌套TList会带来很多麻烦, 我没这么用过, 也没用做具体测试.
      2, Tlist中的结构体是值类型, 无法对下级属性进行操作, 必须接出来处理, 很不方便.
      3, 结构体的嵌套类型还是自己注意一下, 尤其需要申请内存的
      4, 以上3条都属个人理解, 有错误的地方请大家多交流指正.
    上代码
    ------------------------------------------------------------
    unit Unit15;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Generics.Collections;type
      TMyRecI = record
        s:string;
        a:Integer;
      end;
      TMyListI = TList<TMyRecI>;  TMyRecII = record
        str:string;
        b:Integer;
      end;  TMyRecIII = record
        rII:TMyRecII;
        //rI:TMyListI;    //TList<TMyRecI>是需要实例化的
        rI : TArray<TMyRecI>;     //建议用数组
      end;
      TMyListIII = TList<TMyRecIII>;  TForm15 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
        FListIII : TMyListIII;
        FList3 : Tarray<TMyRecIII>;
      public
        { Public declarations }
      end;var
      Form15: TForm15;implementation{$R *.dfm}procedure TForm15.FormCreate(Sender: TObject);
    var
      aRecI:TMyRecI;
      aRecII:TMyRecII;
      aRecIII, aRec3:TMyRecIII;
    begin
      aRecI.s := 's';
      aRecI.a := 0;  aRecII.str:='ss';
      aRecII.b:=10;  SetLength(aRecIII.rI, 1);
      aRecIII.rI[0] := aRecI;
      aRecIII.rII := aRecII;  FListIII := TMyListIII.Create;
      try
        FListIII.Add(aRecIII);
        FListIII.Add(aRec3);
        //FListIII.Items[1].rII.str := 'rii';    //这种写法行不通
        ShowMessage(FListIII.Items[1].rII.str);
        aRecII.str := 'rii';
        //FListIII.Items[1].rII := aRecII;   //这种写法行不通
        aRecIII := FListIII.Items[1];
        aRecIII.rII := aRecII;
        FListIII.Items[1] := aRecIII;
        ShowMessage(FListIII.Items[1].rII.str);
      finally
        FListIII.free;
      end;  SetLength(FList3, 3);
      FList3[0].rII.str := 'a';
      FList3[0].rII.b := 0;
      ShowMessage(IntToStr(length(FList3[0].rI)));
      SetLength(FList3[0].rI, 3);
      ShowMessage(IntToStr(length(FList3[0].rI)));
      FList3[0].rI[0].s := 's1';
      FList3[0].rI[0].a := 1;
      FList3[0].rI[1].s := 's2';
      FList3[0].rI[1].a := 2;
      FList3[0].rI[2].s := 's2';
      FList3[0].rI[2].a := 2;end;end.
      

  8.   

    to:simonhehe
    反是涉及到列表索引引用并赋值的,并且TList<T>里的这个T是“record”均不行,如果T是“class”就可以。我去了结构里所有动态元素,只用基本值类型,也是不行,睢我的代码:unit Unit1;interfaceuses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Generics.Collections;type
      TMyRec1 = record
        a:Integer;
        b:Double;
      end;
      TMyList1 = TList<TMyRec1>;  TMyRec2 = class
        a:Integer;
        b:Double;
      end;
      TMyList2 = TList<TMyRec2>;
    type
      TForm1 = class(TForm)
        btn1: TButton;
        btn2: TButton;
        lst1: TListBox;
        lbl1: TLabel;
        lbl2: TLabel;
        lbl3: TLabel;
        lbl4: TLabel;
        btn3: TButton;
        procedure btn2Click(Sender: TObject);
        procedure btn1Click(Sender: TObject);
      private
        { Private declarations }  public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}
    procedure TForm1.btn1Click(Sender: TObject);
    var
      aRec1,tmp:TMyRec1;
      aList1:TMyList1;
      i:Integer;
    begin
      for i := 0 to 4 do
      begin
        aRec1.a:=10+i;
        aRec1.b:=11+i;    aList1.Add(aRec1);
      end;  tmp.a:=1000;
      tmp.b:=1001;
      //aList3.Delete(0);
      //aList3.Insert(0,aRec3);
      aList1[0].a:=2001;   //这个通不过
      aList1[0].b:=2002;   //这个通不过
      aList1[0]:=tmp;      //这个通不过
    end;procedure TForm1.btn2Click(Sender: TObject);
    var
      aRec2:TMyRec2;
      aList2:TMyList2;
      i:Integer;
    begin
      aRec2:=TMyRec2.Create;
      aList2:=TMyList2.Create;
      for i := 0 to 4 do
      begin
        aRec2.a:=i;
        aRec2.b:=i;    aList2.Add(aRec2);
      end;  aList2[0].a:=100;       //OK
      aList2[0].b:=100;       //OK
    end;end.
    哈哈……
      

  9.   

    按你的需求,得类似这样定义
    type
      PMyRecI=^TMyRecI;
      TMyRecI = record
        s:string;
        a:Integer;
      end;
      TMyListI = TList<PMyRecI>;每个元素用前new,用完dispose
      

  10.   

    LZ说的没错。俺虽然已经装有d2009,特意还是下载了xe装了测试。
    把对应的 record 都换成 指针。
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Generics.Collections, StdCtrls;type  TPMyRecI = ^TMyRecI;
      TMyRecI = record
        s: string;
        a: Integer;
      end;
      TMyListI = TList<TPMyRecI>;  // ----------------------------------
      TPMyRecII = ^TMyRecII;
      TMyRecII = record
        str: string;
        b: Integer;
      end;  // ----------------------------------
      TPMyRecIII = ^TMyRecIII;
      TMyRecIII = record
        rII: TPMyRecII;
        rI: TList<TPMyRecI>;
      end;
      TMyListIII = TList<TPMyRecIII>;  // ----------------------------------
    type
      TForm1 = class(TForm)
        mmo1: TMemo;
        btn1: TButton;
        procedure btn1Click(Sender: TObject);
      private
        FListIII: TMyListIII;
      public
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
    var
      aRecI, aRecI_2: TMyRecI;
      aRecII, aRecII_2: TMyRecII;
      aRecIII: TMyRecIII;
      aLiRec1: TMyListI;
    begin
      // 先构建一个 FListIII
      aLiRec1 := TMyListI.Create;
      aRecI.s := 'aRecI_1';
      aRecI.a := 100;
      aLiRec1.Add(@aRecI);  aRecII.str := 'work';
      aRecII.b := 200;  aRecIII.rI := aLiRec1;
      aRecIII.rII := @aRecII;  FListIII := TMyListIII.Create;
      FListIII.Add(@aRecIII);  if (FListIII <> nil) and (FListIII.Count > 0) then
      begin
        mmo1.Clear;
        with FListIII[0]^ do
        begin
          mmo1.Lines.Add('FListIII[0].rII 赋值之前:');
          mmo1.Lines.Add(Format('FListIII[0].rII.str = %s', [rII.str]));
          mmo1.Lines.Add(Format('FListIII[0].rII = %d', [rII.b]));      mmo1.Lines.Add(Format('FListIII[0].rI = %s', [rI[0].s]));
          mmo1.Lines.Add(Format('FListIII[0].rI = %d', [rI[0].a]));
        end;    aRecII_2.str := 'work too';
        aRecII_2.b := 200000;    aRecI_2.s := 'aRecI_2';
        aRecI_2.a := 100000;    FListIII[0].rII := @aRecII_2;
        FListIII[0].rI[0] := @aRecI_2;    with FListIII[0]^ do
        begin
          mmo1.Lines.Add(#13#10 + 'FListIII[0].rII 赋值之后:');
          mmo1.Lines.Add(Format('FListIII[0].rII.str = %s', [rII.str]));
          mmo1.Lines.Add(Format('FListIII[0].rII = %d', [rII.b]));      mmo1.Lines.Add(Format('FListIII[0].rI = %s', [rI[0].s]));
          mmo1.Lines.Add(Format('FListIII[0].rI = %d', [rI[0].a]));
        end;
      end;  aLiRec1.Free;
      FListIII.Free;
    end;end.
      

  11.   


    我记得在哪儿看到过, delphiXE的泛型对记录类型支持有问题
    论坛有人发现过泛型中使用结构体越界的.
    --------------------------------------------------
    现在还没看到有官方或成熟的例子在泛型中使用结构体的
      

  12.   

    这个问题在网上也没找到,越界的倒是看到了。
    用指针或用类来代替结构,就是麻烦,类可以用TObjectList,不过也得创建;指针就算了,原来没有泛型的时候,用TList的时候才用指针。项目里刚把另外一个TList(P)改成TList(R),不过这个结构里没涉及到更改值,只用Add和AddRange,没这问题。
    听从simonhehe的建议,用TArray<T>来代替了,就是得自己控制动态数组的大小,时不时的检查下,重新Setlength下