可以将记录用作对象的属性吗? [英] Can a record be used as a property of an object?

查看:138
本文介绍了可以将记录用作对象的属性吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想作为对象的属性创建一个记录。问题是当我更改此记录的一个字段时,该对象不知道更改。

I'd like to make a record as an object's property. The problem is that when I change one of the fields of this record, the object isn't aware of the change.

type
  TMyRecord = record
    SomeField: Integer;
  end;

  TMyObject = class(TObject)
  private
    FSomeRecord: TMyRecord;
    procedure SetSomeRecord(const Value: TMyRecord);
  public
    property SomeRecord: TMyRecord read FSomeRecord write SetSomeRecord;
  end;

然后如果我这样做...

And then if I do...

MyObject.SomeRecord.SomeField:= 5;

...不行。

那么当一个记录的字段被写入时,如何使属性设置过程'catch'?也许有一些诀窍如何申报记录?

So how do I make the property setting procedure 'catch' when one of the record's fields is written to? Perhaps some trick in how to declare the record?

更多信息

我的目标是避免使用 OnChange TObject TPersistent $ c>事件(例如 TFont TStringList )。我非常熟悉使用对象,但为了试图清除我的代码,我看到我是否可以使用记录。

My goal is to avoid having to create a TObject or TPersistent with an OnChange event (such as the TFont or TStringList). I'm more than familiar with using objects for this, but in an attempt to cleanup my code a little, I'm seeing if I can use a Record instead. I just need to make sure my record property setter can be called properly when I set one of the record's fields.

推荐答案

考虑这一点,我只需要确保我的记录属性设置器可以被正确调用行:

Consider this line:

MyObject.SomeRecord.SomeField := NewValue;

这实际上是一个编译错误:

This is in fact a compile error:

[DCC错误]:E2064左侧无法分配给

[DCC Error]: E2064 Left side cannot be assigned to

您的实际代码可能是像这样:

Your actual code is probably something like this:

MyRecord := MyObject.SomeRecord;
MyRecord.SomeField := NewValue;

这里发生的是将记录类型的复制到局部变量 MyRecord 。然后,您可以修改此本地副本的字段。这不会修改MyObject中保存的记录。为此,您需要调用属性设置器。

What happens here is that you copy the value of the record type to the local variable MyRecord. You then modify a field of this local copy. That does not modify the record held in MyObject. To do that you need to invoke the property setter.

MyRecord := MyObject.SomeRecord;
MyRecord.SomeField := NewValue;
MyObject.SomeRecord := MyRecord;

或切换到使用引用类型,即一个类,而不是一条记录。

Or switch to using a reference type, i.e. a class, rather than a record.

总而言之,当前代码的问题是SetSomeRecord不被调用,而是修改记录的副本。这是因为记录是值类型,而不是引用类型

To summarise, the problem with your current code is that SetSomeRecord is not called and instead you are modifying a copy of the record. And this is because a record is a value type as opposed to being a reference type.

这篇关于可以将记录用作对象的属性吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆