读写 属性 类型记录

read write property of type record

声明 属性 类型记录有什么缺点吗?

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

指令 Myobject.SomeRecord.xxx := yyy 如何在后台工作(我认为这实际上行不通)?

如果不行,记录属性怎么办?避免它并像下面这样声明 TMyobject 是否更好?

  TMyObject = class(TObject)
  public
    SomeRecord: TMyRecord;
  end;

你说得对 Myobject.SomeRecord.xxx := yyy 不会按你想要的方式工作。它将调用 属性 getter,返回记录的 copy,然后您将更新副本的 xxx 字段,而不是原本的。本质上,生成的代码将像这样:

var tmp: TMyRecord;
tmp = Myobject.FSomeRecord;
tmp.xxx := yyy;

除非您需要 属性 的 RTTI,否则没有充分的理由声明只直接访问字段的读+写 属性。只需公开 public 对该字段的访问权限即可。

避免这种情况的一种方法是将 属性 声明为指向记录的指针(如果您只需要访问 fields/methods 中的 记录):

TYPE
  TMyRecord = RECORD
                Field1  : INTEGER;
              END;
  PMyRecord = ^TMyRecord;

TYPE
  TMyClass  = CLASS
          PRIVATE
            FMyRecord   : TMyRecord;
            FUNCTION    GetRec : PMyRecord;
          PUBLIC
            PROPERTY    MyRec : PMyRecord Read GetRec;
          END;

{ TMyClass }

FUNCTION TMyClass.GetRec : PMyRecord;
  BEGIN
    Result:=@FMyRecord
  END;

.
.
.
VAR
  MC    : TMyClass;
.
.
.
MC.MyRec.Field1:=12
.
.
.

由于“扩展语法”,您可以short-circuit使用

的正常语法
MC.MyRec^.Field1:=12

MC.MyRec.Field1:=12

但不能用于以下用途:

VAR NewRec : TMyRecord := MC.MyRec;

必须编码为

VAR NewRec : TMyRecord := MC.MyRec^;

除非您为 PMyRecord 引入一个 RECORD HELPER,它实现了对 TMyRecord 的隐式转换:

TYPE
  PMyRecHelper  = RECORD HELPER FOR PMyRecord
                    CLASS OPERATOR Implicit(P : PMyRecord) : TMyRecord;
                  END;

{ PMyRecHelper }

CLASS OPERATOR PMyRecHelper.Implicit(P : PMyRecord) : TMyRecord;
  BEGIN
    Result:=P^
  END;

不幸的是,上面的代码在编译时不起作用。 Delphi 不允许在记录助手中使用运算符重载...

因此,在实施最后一项之前,您只有 semi-working 实施...