2009-07-12 54 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和记录构造搞乱恕我直言。