Delphi中的变体记录中的帮助函数

4
Delphi 10.2: 我有一个变量记录定义:
type
  TIPMCCmdPacket = packed record
    TransactionID: Word;
    FuncCode: Word;
    DataLen: Word;
    case byte of
         //raw data buffer
      0: (RawBuf: Array[0..16383] of Byte);
         //error response
      1: (ErrCode: Word;                            //error type code
          ErrLen: Word;                             //length of error msg/data
          ErrBuf: Array[0..16379] of AnsiChar);     //err msg buffer
         //normal response, usually an ansistring
      2: (BufCnt: Word;                             //byte count
          Buffer: Array[0..16381] of Byte);         //response data
         //structured-data response
      3: (RecType: Word;                            //type code of record 
          RecCnt: Word;                             //# of records
          RecSize: Word;                            //size of each record
          RecBuf: Array[0..16377] of Byte);         //data block
  end;

我想为这个记录添加一些辅助函数,但是普通记录辅助函数的语法在变体记录中使用会引发语法错误,并且该语言参考文献中没有提及如何在变体记录中使用辅助函数的情况。我是否有所遗漏,有没有其他方法可以做到这一点?


我猜你所说的“记录助手”是指成员函数和过程。("记录助手" 是一个不同的概念。) - Andreas Rejbrand
我完全忘记了这种语法在记录和类上同样适用。谢谢! - SteveS
1
记录助手的真正有用之处在于它们可以用于非类类型,这些类型不是记录:整数类型、数组等。这样,您就可以为这些类型提供“成员函数”。我们每天都使用 TIntegerHelperTStringHelper。(我在我的 A 中使用 TIntegerHelper!) - Andreas Rejbrand
这是我没有养成的习惯,因为我从来没有做过除了Windows/VCL开发以外的事情,也不需要关注字符串索引等差异,并且我已经使用传统函数35年了。但这是我需要养成的习惯。 - SteveS
确实!我也只使用 VCL 开发 Windows 应用程序。 - Andreas Rejbrand
1个回答

4
问题在于记录的变体部分必须是记录的最后一部分,而在成员列表中不允许在方法和属性下方有字段。这使得将两个特性组合在一起很困难。但是,有多种有效避开此限制的方法。
方法一:虚拟记录
您可以使用虚拟记录来表示变体部分:
type
  TTest = record
    Name: string;
    Age: Integer;
    Dummy: record
      case Byte of
        0: (Data: Integer);
        1: (Tag: Byte);
    end;
    procedure Test;
  end;

这样做的明显效果是你需要写t.Dummy.Data而不是t.Data

方法2:记录辅助函数

如果那种方法不能被接受,你可以使用记录辅助函数

type
  TTest = record
    Name: string;
    Age: Integer;
    case Byte of
        0: (Data: Integer);
        1: (Tag: Byte);
  end;

  TTestHelper = record helper for TTest
    procedure Test;
  end;

procedure TTestHelper.Test;
begin
  ShowMessage(Name);
  ShowMessage(Age.ToString);
  ShowMessage(Data.ToHexString);
end;

第三种方法:使用可见性关键字作为分隔符

David Heffernan 在评论中建议您可以使用 public 可见性关键字来规避您正在观察的语法限制。通过使用这个关键字,您可以编写如下代码:

type
  TTest = packed record
    procedure Test;
  public
    Name: string;
    Age: Integer;
    case Byte of
        0: (Data: Integer);
        1: (Tag: Byte);
  end;

没有不想要的副作用。这是因为默认可见性是公共的,所以所有成员都是公共的--在public之前和之后。


2
使用public来分割部分怎么样? - David Heffernan
1
@David:确实,这样更加简洁。你可以将其发布为答案,以便获得功劳。 - Andreas Rejbrand
1
如果你能做到那就很酷。我现在很忙,不太在意功劳。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接