2013-10-25 59 views
2

當我構建自定義組件時,我可能會實現發佈的持久性屬性。例如...發佈的持久性屬性 - 我應該使用FMyPersistent.Assign(Value)還是FMyPersistent:= Value?

type 
    TMyComponent = class(TComponent) 
    private 
    FMyPersistent: TMyPersistent;  
    ... 
    public 
    ... 
    published 
    property MyPersistent: TMyPersistent read FMyPersistent write SetMyPersistent; 
    ... 
    end; 

注意該過程SetMyPersistent還沒有實現,這就是下一步的用武之地。我用鼠標右鍵單擊該對象並選擇「完整的類的光標」(或Shift + Control + C)來調用代碼完成。當它自動創建此屬性setter,它會自動將分配代碼...

procedure TMyComponent.SetMyPersistent(const Value: TMyPersistent); 
begin 
    FMyPersistent := Value; 
end; 

現在,這是不錯的,它繼續和完成了我這項任務。然而,在正常情況下,我總是習慣於用...

procedure TMyComponent.SetMyPersistent(const Value: TMyPersistent); 
begin 
    FMyPersistent.Assign(Value); 
end; 

在財產是一種情況下,如StringInteger,然後直接分配是這樣做的正確方法。但是,在實施TPersistent的已發佈財產時,是不是使用TPersistent.Assign的正確方法?

使用這兩種賦值機制的本質區別是什麼?因爲如果使用TPersistent.Assign是合適的事情,那麼代碼完成有一個小缺陷 - 也就是說,假設FMyPersistent := Value被認爲是「錯誤的」。

+2

你問你是否應該將內容分配給你自己的對象,而不是將對象替換爲另一個對象,並泄漏前一個對象?我想你可以自己解決這個問題!如果您的對象在其構造函數中創建了一個FMyPersistent,並將其釋放到其析構函數中,那麼請使用Assign,否則,如果它是弱引用,並且您沒有擁有該對象或釋放該對象,請使用變量FField:= Value。這都是關於所有權。 –

+0

那麼我原來的問題標題就像是「爲什麼Cursor的Complete Class會直接分配已發佈的持久性屬性?」但是我改變了它,因爲它並不真正符合問題的核心。這真的很奇怪,爲什麼這個特定的實例會觸發IDE編寫一些不正確的代碼,只能讓你不得不更換它。我想知道爲什麼IDE會做這樣的事情,但這個問題當然會被認爲是無關緊要的。 –

+0

@Jerry IDE的想法並不重要。它沒有大腦。你想要參考還是副本?這就是問題所在。你決定。 –

回答

3

致電Assign。這就是爲什麼你首先擁有一個財產創造者。如果您直接覆蓋該字段,則不需要安裝程序。覆蓋它會泄漏您在構造函數中創建的原始對象。在對象檢查器中修改屬性時,您還會注意到IDE中的訪問衝突。

代碼完成會在它創建的每個設置器中放入相同的代碼。對於在最終將值存儲在字段中之前需要執行其他工作的屬性,所以field-storage語句是正確的。 IDE不知道你真正想要什麼。

+0

另一方面,如果不希望在它的位置分配一個新的持久性,那麼實際上甚至不應該有一個setter,只是一個只讀持久性屬性。 –

+0

歡迎您這樣做,但該屬性在Object Inspector中不可編輯。 Object Inspect不會呈現只讀屬性,並且在它分配屬性時,它始終如此,就像通過賦值語句一樣。它不會調用「Assign」。所以,如果你希望你的財產可以用同樣的方式編輯,那麼'TFont'和'TPen'屬性是可編輯的,你需要提供一個setter,並且你需要在其中調用'Assign'(或者道德等價物)。 –

+0

不幸的是,這個答案在某些情況下是錯誤的,例如當屬性是TDataset並且不是我擁有的對象時。 –

3

你應該問自己的問題是 - 誰擁有涉及的對象?如果您的組件創建並擁有FMyPersistent,則使用FMyPersistent.Assign(Value)將值從Value複製到FPersistent。如果FMyPersistent僅指向其他人擁有的外部對象,則改爲使用FMyPersistent := Value

相關問題