Delphi中记录体做为属性的赋值方法

Delphi中记录体做为属性的赋值方法

1. 起源

此问题源于[秋风人事档案管理类别]用Delphi XE重编译中所发现。

快十年了,当初Delphi 7所编写项目,想用Delphi
XE重新编译,并打算做为Free软件发表,编译错误中发现此问题,感觉颇有些意思,遂记录下来,以做备忘。

自Delphi 2009之后,转做c#之WinForm界面开发,Delphi
2010自此未实际做过项目,因而至此才境遇此题材。

此时Delphi
XE快快已至XE10版。因情结而不愿XE2之后的use方法,遂决定以Delphi
XE做为工具,重整老项目。

而此题材,简单来讲,就是当记录体(record)做为属性出现时,其赋值问题。

 

2. 赋值

诸如,我有一笔录体属性如下(这里以TPoint表明问题,实际项目中为自定义记录体):

type
  TForm1 = class(TForm)
    btnTest: TButton;
    procedure btnTestClick(Sender: TObject);
  private
    { Private declarations }
    FPoint: TPoint;
  public
    { Public declarations }
    property Point: TPoint read FPoint write FPoint;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btnTestClick(Sender: TObject);
begin
  //Point.X := 12; //如此赋值不成功,报错为Left side cannot be assigned to
  //Point.Y := 12;
  with Point do
  begin
    X := 12;
    Y := 12;
  end;
  ShowMessage(Format('x: %d, y: %d', [Point.X, Point.Y]));
end;

直白赋于做为属性的record值,比如Point.X :=
12,编译都不可能因此。大家得以理解为面向对象封装问题不容许操作其内部数据,因为记录体为值类型。

人事档案,但事有折中,借with语句,即可方便赋值。所以在昔日项目中,多用此写法,简洁而便宜,而这种写法在Delphi
2009及往日版本,都帮忙,可能是Delphi编译器的BUG吧!

假使是,我爱不释手这些BUG,它简洁了我的写法,特别是性质有多重嵌套时。

 

3. 不再帮助

Delphi命运多舛,像个不可能决定自己命局的闺女一样被卖来卖去。工作缘故换了开发工具,十多年的Delphi开发从此搁置,不曾想其间多少变化,如今再用,细微变化已别于昔时。

如上面代码,用with语句赋值,也不算了,报错为[DCC Error] Unit1.pas(34): E2064 Left side
cannot be assigned to.

baidu看有没有人接近疑惑?可能国内用Delphi渐少原因呢,竟没找到类似问题,于是stackoverflow一下,果然碰着一根筋的同伙:

Left side cannot be assigned for a record
type

Delphi “E2064 Left side cannot be assigned to” error appeared when
upgrading a project from 2009 to
XE

Delphi 2010+ and “Left side cannot be assigned to” in read-only
records: can this be
disabled?

看诸回复,大意是Delphi
2010及今后版本其编译器检查比原先更为严谨,其中还有人致谢这么更改。研究相比较强烈,说吗的都有。日!

与提问者一样,我只想大概地做为属性以记录需的的数额,仅此而已。那是一个一心可行的言语特色,就如此给干了,这是历史的滞后!

 

4. 化解方法

这条路关闭了,总还有任何路,是不是?编译器想必正是处理属性为Get、Set形式,而加以特别处理?

小结下啊!假诺还想用此方法,就折中下:

a. 直接换属性为字段,即

property Point: TPoint read FPoint write FPoint;

换为Point: TPoint;

这条措施违背于面向对象封装,不佳,但能用。

b. 假如自定义record,可换为class,这思路中。

c. 以指针形式去赋值:

procedure TForm1.btnTestClick(Sender: TObject);
begin
  with PPoint(@Point)^ do
  begin
    X := 12;
    Y := 12;
  end;
  ShowMessage(Format('x: %d, y: %d', [Point.X, Point.Y]));
end;

自我个人倾向于这多少个。自定义记录体,再定义个指向它的指针结构,就可以了。

d. 以临时变量代之,反赋回去:

procedure TForm1.btnTestClick(Sender: TObject);
var
  p: TPoint;
begin
  with p do
  begin
    X := 12;
    Y := 12;
  end;
  Point := p;
  ShowMessage(Format('x: %d, y: %d', [Point.X, Point.Y]));
end;

这应该是明媒正娶写法,但总感到繁琐令人不快。

左右是少了前头版本这自然淋漓简洁随意的写法,蛋疼之极也!

admin

网站地图xml地图