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多个参数,不能省了)
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多个参数,不能省了)
begin
FListIII[0].rII.str:=aRecII.str;
FListIII[0].rII.b:=aRecII.b;
end;
and Created??
and
TMyRecIII = record
rII:TMyRecII;
rI:TMyListI;
end;
TMyRecIII with Type inside,
FListIII[0].rII:=aRecII;
aRecII with String inside.
record 是值类型的,区别于引用类型的class,rocord传递是按值复制的而非复制引用,
这是本质上区别, record1 := record2 是不能通过编译的。你的 FListIII 是怎么定义和创建的先?
太晚了,先呼呼
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楼兄弟加上的
aList4[0].a:=100;
aList4[0].b:=100;有人知道这是为什么啊(要下XE2下试通过的)
要替换TList<T>里的某个元素,难道要这样:
Delete(AIndex);
Insert(AIndex,T);
这也太丑陋了吧!!!!
按着你的思路写了个测试代码, 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.
反是涉及到列表索引引用并赋值的,并且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.
哈哈……
type
PMyRecI=^TMyRecI;
TMyRecI = record
s:string;
a:Integer;
end;
TMyListI = TList<PMyRecI>;每个元素用前new,用完dispose
把对应的 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.
我记得在哪儿看到过, delphiXE的泛型对记录类型支持有问题
论坛有人发现过泛型中使用结构体越界的.
--------------------------------------------------
现在还没看到有官方或成熟的例子在泛型中使用结构体的
用指针或用类来代替结构,就是麻烦,类可以用TObjectList,不过也得创建;指针就算了,原来没有泛型的时候,用TList的时候才用指针。项目里刚把另外一个TList(P)改成TList(R),不过这个结构里没涉及到更改值,只用Add和AddRange,没这问题。
听从simonhehe的建议,用TArray<T>来代替了,就是得自己控制动态数组的大小,时不时的检查下,重新Setlength下