首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Delphi中记录类型属性的"Left side cannot to“

Delphi中记录类型属性的"Left side cannot to“
EN

Stack Overflow用户
提问于 2009-03-06 21:32:04
回答 8查看 20.3K关注 0票数 23

我很想知道为什么Delphi将记录类型属性视为只读:

代码语言:javascript
复制
  TRec = record
    A : integer;
    B : string;
  end;

  TForm1 = class(TForm)
  private
    FRec : TRec;
  public
    procedure DoSomething(ARec: TRec);
    property Rec : TRec read FRec write FRec;
  end;

如果我试图将一个值赋给Rec属性的任何成员,我会得到"Left side cannot be assigned to“错误:

代码语言:javascript
复制
procedure TForm1.DoSomething(ARec: TRec);
begin
  Rec.A := ARec.A;
end;

同时也允许对底层字段执行相同的操作:

代码语言:javascript
复制
procedure TForm1.DoSomething(ARec: TRec);
begin
  FRec.A := ARec.A;
end;

对这种行为有什么解释吗?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2009-03-06 22:11:20

由于"Rec“是一个属性,编译器对它的处理稍有不同,因为它必须首先计算属性decl的"read”。考虑这一点,它在语义上与您的示例等效:

代码语言:javascript
复制
...
property Rec: TRec read GetRec write FRec;
...

如果你这样看它,你可以看到对" Rec“的第一个引用(在点”.“之前)必须调用GetRec,这将创建一个Rec的临时本地副本。这些临时文件被设计为“只读”。这就是你要遇到的。

您可以在这里做的另一件事是将记录的各个字段分解为包含类上的属性:

代码语言:javascript
复制
...
property RecField: Integer read FRec.A write FRec.A;
...

这将允许您通过属性直接赋值给类实例中嵌入记录的字段。

票数 39
EN

Stack Overflow用户

发布于 2009-03-06 23:22:29

是的,这是一个问题。但是这个问题可以使用记录属性来解决:

代码语言:javascript
复制
type
  TRec = record
  private
    FA : integer;
    FB : string;
    procedure SetA(const Value: Integer);
    procedure SetB(const Value: string);
  public
    property A: Integer read FA write SetA;
    property B: string read FB write SetB;
  end;

procedure TRec.SetA(const Value: Integer);
begin
  FA := Value;
end;

procedure TRec.SetB(const Value: string);
begin
  FB := Value;
end;

TForm1 = class(TForm)
  Button1: TButton;
  procedure Button1Click(Sender: TObject);
private
  FRec : TRec;
public
  property Rec : TRec read FRec write FRec;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Rec.A := 21;
  Rec.B := 'Hi';
end;

这样编译和工作都没有问题。

票数 22
EN

Stack Overflow用户

发布于 2014-05-05 17:04:13

我经常使用的一种解决方案是将属性声明为指向记录的指针。

代码语言:javascript
复制
type
  PRec = ^TRec;
  TRec = record
    A : integer;
    B : string;
  end;

  TForm1 = class(TForm)
  private
    FRec : TRec;

    function GetRec: PRec;
    procedure SetRec(Value: PRec);
  public
    property Rec : PRec read GetRec write SetRec; 
  end;

implementation

function TForm1.GetRec: PRec;
begin
  Result := @FRec;
end;  

procedure TForm1.SetRec(Value: PRec);
begin
  FRec := Value^;
end;

这样,直接赋值Form1.Rec.A := MyInteger将起作用,但Form1.Rec := MyRec也会按照预期将MyRec中的所有值复制到FRec字段中。

这里唯一的缺陷是,当您希望实际检索要使用的记录的副本时,您必须使用类似于MyRec := Form1.Rec^的命令

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/620506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档