【问题标题】:Delphi: Record constructor vs factory functionDelphi:记录构造函数与工厂函数
【发布时间】:2009-07-12 19:30:20
【问题描述】:

那么初始化记录的首选方式是什么?

带有“工厂功能”:

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;

感觉构造函数的东西比较封装,但是看代码的时候容易混淆。它使它看起来像一个缺少免费调用的类。打字也多了……

为什么你更喜欢其中一个?

【问题讨论】:

    标签: delphi constructor record


    【解决方案1】:

    我更喜欢类,但如果我必须使用记录,我喜欢尽可能将它们视为类。所以我使用了记录构造函数。

    但是记录和单位有一个烦人的错误。如果一个函数返回一条记录(带有方法),如果你想访问这些方法,它会产生一个内部错误。您可以通过将其分配给另一个变量来规避它:

    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;
    

    【讨论】:

    • 我也使用记录构造函数。如果愿意,您可以将其命名为不同于“创建”的名称,这样您就知道它是一条记录。
    • 仅供参考您提到的内部错误问题似乎已在 D2010 中修复。
    • 问题是关于构造函数,而不仅仅是一个方法。如果我们对构造函数遵循相同的符号,那么很难从代码中理解它是记录还是类的实例。对于类,这意味着内存泄漏,因此任何看到该代码的人都必须检查它是真的记录还是类。所以我认为这是不好的方式。
    【解决方案2】:

    我更喜欢“工厂方法”之类的

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

    单独的工厂函数泄漏封装和记录构造函数只会混淆恕我直言。

    【讨论】:

      【解决方案3】:

      在我创建的一个 Delphi 项目中,我使用记录而不是类来减少列表的开销。我将在动态数组中有数百条记录,因此我创建了两条记录。 第一条记录是针对项目本身的。这些字段被设为私有(是的,您可以使用私有/受记录的保护)并将只读属性添加到公共部分。还添加了一个额外的构造函数来以正确的方式初始化记录。此设置允许我保护内容免受其他开发人员的此记录。 第二条记录只是前一个记录类型的动态数组的包装器。该数组将是私有的,我添加了获取、添加和删除此列表中记录的方法。因此,整个列表受到保护,不会被其他开发人员误用,而且开销也比常规的 TList/TObjectList 解决方案少得多。

      请记住,记录不是类。您不能继承构造函数和其他方法。它们的功能比 WIN32 环境中的真实类少。在 .NET 中,它们只是再次提升为类。 当开发人员可以轻松地修改记录中每个字段的内容时,使用添加构造函数并不是很有用。您应该使用构造函数来保护这些字段。

      【讨论】:

        【解决方案4】:

        我通常不会为记录创建构造函数。它不兼容所有版本(和 FPC)。此外,它们通常只在一个地方使用,而且通常一个 fillchar 就足够了。

        【讨论】:

        • 使用 FillChar( ) 来初始化带有值的记录有点困难,不是吗?
        猜你喜欢
        • 2012-01-31
        • 2014-11-03
        • 1970-01-01
        • 2010-10-12
        • 1970-01-01
        • 1970-01-01
        • 2014-02-18
        • 1970-01-01
        • 2017-01-21
        相关资源
        最近更新 更多