2009-07-12 90 views
17

那麼初始化記錄的首選方法是什麼?Delphi:記錄構造函數與工廠函數

以「工廠功能」:

TMyRecord = record 
    valueX: integer; 
    valueY: integer; 
end; 

function MyRecord(const AValueX, AValueY: integer): TMyRecord; 
begin 
    result.valueX := AValueX; 
    result.valueY := AValueY; 
end; 

var 
    myrec: TMyRecord; 
begin 
    myrec := MyRecord(1, 2); 
end; 

或構造函數:

TMyRecord = record 
    valueX: integer; 
    valueY: integer; 
    constructor Create(const AValueX, AValueY: integer); 
end; 

constructor TMyRecord.Create(const AValueX, AValueY: integer); 
begin 
    self.valueX := AValueX; 
    self.valueY := AValueY; 
end; 

var 
    myrec: TMyRecord; 
begin 
    myrec := TMyRecord.Create(1, 2); 
end; 

我覺得構造事情更封裝,但它使閱讀代碼的時候很容易混淆。它使它看起來像一個沒有免費電話的班級。這也是更多類型...

爲什麼你會喜歡一個在另一個?

回答

11

我更喜歡類,但是如果我必須使用記錄,我喜歡把它們看作與類儘可能類似。所以我使用記錄構造函數。

但是有一個記錄和單位惱人的錯誤。如果一個函數返回一個記錄(包含方法),如果你想訪問這些方法,它會產生一個內部錯誤。您可以通過將其分配給另一個變量來規避此問題:

type 
    TMyRec = record 
    .. 
    procedure X; 
    end; 


function GetRec: TMyRec; 



procedure Test; 
var 
    r1, r2 : TMyRec; 
begin 
    r1 := GetRec; 
    r1.X; // internal error 
    r2 := r1; 
    r2.X; // No internal error; 
+4

我也使用記錄構造函數。如果你喜歡,你可以命名它與「創建」不同,所以你知道它是一個記錄。 – 2009-07-13 02:58:58

+5

僅供參考您提到的內部錯誤問題在D2010中似乎已得到修復。 – 2010-05-09 23:06:56

0

我通常不會爲記錄創建構造函數。它不兼容所有版本(和FPC)。此外,通常它們僅用於一個地方,通常fillchar就足夠了。

1

在我創建的Delphi項目中,我使用記錄而不是類來減少列表中的開銷量。我將在動態數組中創建數百條記錄,所以我創建了兩條記錄。 第一個記錄是該項目本身。這些字段是私有的(是的,您可以使用私有/受保護的記錄)並向公共部分添加只讀屬性。還添加了一個額外的構造函數以正確的方式初始化記錄。這種設置使我能夠保護其他開發人員的記錄內容。 第二條記錄僅僅是前一個記錄類型的動態數組的一個包裝。該數組將是私人的,我添加了方法來獲取,添加和刪除列表中的記錄。因此,整個列表不會受到其他開發人員的誤用,並且比常規TList/TObjectList解決方案的開銷少得多。

請記住,記錄不是類。你不能繼承構造函數和其他方法。在WIN32環境中,它們的功能比真正的類少。在.NET中,他們只是再次升級到類。 當開發人員可以輕鬆修改記錄中每個字段的內容時,使用添加構造函數並不是很有用。您應該使用構造函數來保護這些字段。

2

我更喜歡「工廠法」之類

function TMyRecord.CreateRec(const AValueX, AValueY: integer): TMyRecord; 

獨立工廠函數泄漏incapsulation和記錄構造搞亂恕我直言。