宣告記錄型別的屬性有什么缺點嗎?
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;
uj5u.com熱心網友回復:
你是對的,Myobject.SomeRecord.xxx := yyy不會按照你想要的方式作業。它將呼叫屬性 getter,回傳記錄的副本,然后您將更新xxx副本的欄位,而不是原始欄位。本質上,生成的代碼將如下所示:
var tmp: TMyRecord;
tmp = Myobject.FSomeRecord;
tmp.xxx := yyy;
除非您需要該屬性的 RTTI,否則沒有充分的理由宣告一個直接訪問欄位的讀寫屬性。只需公開對該欄位的公共訪問權限。
uj5u.com熱心網友回復:
避免這種情況的一種方法是將屬性宣告為記錄的指標(如果您只需要訪問記錄中的欄位/方法):
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
.
.
.
由于“擴展語法”,您可以將正常語法短路
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 不允許在記錄助手中使用運算子多載...
因此,在實施最后一項之前,您只有一個半作業的實施......
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/424522.html
標籤:德尔福
上一篇:在Win10/11下使用ModernIFileDialog打開/保存對話框與Delphi7應用程式
下一篇:Delphi中檢查FreeOnTerminate=True的非暫停創建的TThread是否仍在執行的正確方法是什么?
