把一个"结构体"当做属性后碰到的问题
当我把一个"结构体"在类中当做属性后, 在实用中可以直接读取结构体成员, 但不能直接写入...
下面是由此引发的小练习:
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; Button5: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button5Click(Sender: TObject); end; TMyClass = class strict private FPos: TPoint; procedure SetPos(const Value: TPoint); public property Pos: TPoint read FPos write SetPos; //属性 Pos 对应一个点结构 end; var Form1: TForm1; implementation {$R *.dfm} { TMyClass } procedure TMyClass.SetPos(const Value: TPoint); begin FPos := Value; end; {测试} procedure TForm1.Button1Click(Sender: TObject); var obj: TMyClass; begin obj := TMyClass.Create; ShowMessageFmt('%d, %d', [obj.Pos.X, obj.Pos.Y]); //可以直接访问结构中的元素 // obj.Pos.X := 11; //但不能直接给结构中的元素赋值 // obj.Pos.Y := 22; obj.Free; end; //变通一 procedure TForm1.Button2Click(Sender: TObject); var obj: TMyClass; begin obj := TMyClass.Create; obj.Pos := Point(22,33); // ShowMessageFmt('%d, %d', [obj.Pos.X, obj.Pos.Y]); obj.Free; end; //变通二 procedure TForm1.Button3Click(Sender: TObject); var obj: TMyClass; pt: TPoint; begin obj := TMyClass.Create; pt.X := 33; pt.Y := 44; obj.Pos := pt; ShowMessageFmt('%d, %d', [obj.Pos.X, obj.Pos.Y]); obj.Free; end; //变通三(假如属性的 get 不是方法) procedure TForm1.Button4Click(Sender: TObject); var obj: TMyClass; p: PPoint; begin obj := TMyClass.Create; p := Addr(obj.Pos); p.X := 44; p.Y := 55; ShowMessageFmt('%d, %d', [obj.Pos.X, obj.Pos.Y]); obj.Free; end; //变通四(假如属性的 get 不是方法) procedure TForm1.Button5Click(Sender: TObject); var obj: TMyClass; begin obj := TMyClass.Create; PPoint(Addr(obj.Pos)).X := 55; PPoint(Addr(obj.Pos)).Y := 66; ShowMessageFmt('%d, %d', [obj.Pos.X, obj.Pos.Y]); obj.Free; end; end.
练习二:
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); end; TMyClass = class private FPos: TPoint; function GetPos: TPoint; procedure SetPos(const Value: TPoint); function GetXY(const Index: Integer): Integer; procedure SetXY(const Index, Value: Integer); public property Pos: TPoint read GetPos write SetPos; property X: Integer index 0 read GetXY write SetXY; property Y: Integer index 1 read GetXY write SetXY; end; var Form1: TForm1; implementation {$R *.dfm} { TMyClass } function TMyClass.GetPos: TPoint; begin Result := FPos; end; procedure TMyClass.SetPos(const Value: TPoint); begin FPos := Value; end; function TMyClass.GetXY(const Index: Integer): Integer; begin Result := 0; case Index of 0: Result := FPos.X; 1: Result := FPos.Y; end; end; procedure TMyClass.SetXY(const Index, Value: Integer); begin case Index of 0: FPos.X := Value; 1: FPos.Y := Value; end; end; {测试} procedure TForm1.FormCreate(Sender: TObject); var obj: TMyClass; begin obj := TMyClass.Create; obj.X := 11; obj.Y := 22; ShowMessageFmt('%d, %d', [obj.Pos.X, obj.Pos.Y]); obj.Free; end; end.