Delphi 2010:令人困惑的泛型类型 TList 场景?按值传递还是按引用传递?
几天前,我在项目中使用 Generic TList 时遇到了一个问题。我在一个简单的测试项目中对其进行了测试,并遇到了同样的问题。这是确切的代码:
type
TMyPoint = record
x: Integer;
y: Integer;
end;
TShape = record
Corners: TList<TMyPoint>;
end;
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
Shape_List: TList<TShape>;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Shape: TShape;
FirstPoint: TMyPoint;
SecondPoint: TMyPoint;
Temp: TMyPoint;
begin
// Create the corners list
Shape.Corners := TList<TMyPoint>.Create;
// Add the first point to corners
FirstPoint.x := 10;
FirstPoint.y := 20;
Shape.Corners.Add(FirstPoint);
// Add the shape to the Shape_List
Shape_List.Add(Shape);
// Clear the shape corners
Shape.Corners.Clear;
// Add another point to corners
SecondPoint.x := 100;
SecondPoint.y := 200;
Shape.Corners.Add(SecondPoint);
// Show the x of the first point of the first shape
Label1.Caption := IntToStr(Shape_List[0].Corners[0].x);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Shape_List := TList<TShape>.Create;
end;
Label1.Caption 将是 100 而不是 10 !为什么会这样呢?我认为 TList.Add(const value)
是按值传递而不是按引用传递!
I encountered a problem some days ago while working with Generic TList in the middle of a project. I tested it in a simple test project and got the same problem. Here is the exact code:
type
TMyPoint = record
x: Integer;
y: Integer;
end;
TShape = record
Corners: TList<TMyPoint>;
end;
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
Shape_List: TList<TShape>;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Shape: TShape;
FirstPoint: TMyPoint;
SecondPoint: TMyPoint;
Temp: TMyPoint;
begin
// Create the corners list
Shape.Corners := TList<TMyPoint>.Create;
// Add the first point to corners
FirstPoint.x := 10;
FirstPoint.y := 20;
Shape.Corners.Add(FirstPoint);
// Add the shape to the Shape_List
Shape_List.Add(Shape);
// Clear the shape corners
Shape.Corners.Clear;
// Add another point to corners
SecondPoint.x := 100;
SecondPoint.y := 200;
Shape.Corners.Add(SecondPoint);
// Show the x of the first point of the first shape
Label1.Caption := IntToStr(Shape_List[0].Corners[0].x);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Shape_List := TList<TShape>.Create;
end;
The Label1.Caption will be 100 not 10 ! Why is it like this? I thought TList.Add(const value)
is pass-by-value not pass-by-reference!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在您的程序中添加了一些注释,以准确指出“错误”所在。
Added some comments to your procedure to point out exactly where the "bug" is.
添加
FirstPoint
后,您清除
Corners
(之后,列表为空)。然后添加SecondPoint
,它成为第一个元素(索引 0)。编辑:为了说明:
Shape1.Corners
和Shape2.Corners
指向同一列表。After adding the
FirstPoint
, youClear
theCorners
(after that, the list is empty). Then you addSecondPoint
which becomes the first element (index 0).Edit: To illustrate:
Shape1.Corners
andShape2.Corners
point to the same list.不,它是通过引用传递的,因为它作为常量参数传递(请参阅:http://docwiki.embarcadero.com/VCL/en/Generics.Collections.TList.Add)。
No, it is passed by reference since it is passed as a constant parameter (see: http://docwiki.embarcadero.com/VCL/en/Generics.Collections.TList.Add).