delphi вспомогательные функции в записях вариантов - PullRequest
4 голосов
/ 17 апреля 2020

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;

Я хочу добавить к этому пару вспомогательных функций, но обычный синтаксис для помощников записей выдает синтаксические ошибки при использовании в записях вариантов и в справочнике по языку не упоминается случай использования помощников с вариантом записи. Есть ли способ сделать это, что мне не хватает?

1 Ответ

3 голосов
/ 17 апреля 2020

Проблема в том, что вариантная часть записи должна быть последней частью записи, в то время как поля недопустимы под методами и свойствами в списке членов. Это затрудняет объединение двух функций. Однако существуют различные способы эффективно обойти это ограничение.

Метод 1: фиктивная запись

Вы можете использовать фиктивную запись для вариантной детали:

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;

Метод 3: Использовать ключевое слово видимости в качестве разделителя

Дэвид Хеффернан предложил в комментарии, что вы можете использовать ключевое слово public visibility, чтобы обойти ограничение syntacti c, которое вы наблюдаете. Используя это ключевое слово, вы можете написать

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

, который не имеет нежелательных побочных эффектов. Это связано с тем, что видимость по умолчанию - publi c, поэтому все члены публикуются c - как до, так и после public.

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...