Как определить операторы неявного преобразования для взаимозависимых записей? - PullRequest
13 голосов
/ 21 апреля 2009

Я использую перегрузку оператора для записей в Delphi 2006. (Пожалуйста, не отвечайте на этот вопрос, сказав мне не делать этого.)

У меня есть два типа записей с перегруженным оператором неявным . Они оба только в реализации модуля, а не через интерфейс.

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

Вот упрощенный пример того, что я пытаюсь сделать:

implementation

type
  TMyRec1 = record
    Field1 : Integer;
    class operator Implicit(a: TMyRec2): TMyRec1;  // <---- Undeclared Identifier here.
  end;

  TMyRec2 = record
    Field2: Integer;
    class operator Implicit(a: TMyRec1): TMyRec2;
  end;

class operator TMyRec1.Implicit(a:TMyRec2): TMyRec1;
begin
  Result.Field1 := a.Field2;
end;

class operator TMyRec2.Implicit(a:TMyRec2): TMyRec2;
begin
  Result.Field2 := a.Field1;
end;

Ответы [ 2 ]

13 голосов
/ 21 апреля 2009

Вы не можете иметь предварительные объявления для типов записей. Определите оба оператора Implicit во втором типе:

type
  TMyRec1 = record
    Field1 : Integer;
  end;

  TMyRec2 = record
    Field2: Integer;
    class operator Implicit(a: TMyRec2): TMyRec1;
    class operator Implicit(a: TMyRec1): TMyRec2;
  end;

Цитирование из справки :

Неявные преобразования должны предоставляться только там, где это абсолютно необходимо, и следует избегать рефлексивности. Лучше всего, чтобы тип B неявно преобразовывался в тип A, а тип A не знал типа B (или наоборот).

3 голосов
/ 15 января 2011

Вы могли бы быть в состоянии сделать это с помощниками записи.

Ниже я недавно сделал, чтобы обойти невозможность иметь forward record объявление записи.

Используется конструкция record helper, которая, как и implicit type casts, также имеет недостатки.
Наиболее важным из них является то, что будет применяться только ближайший record helper для определенного типа record.

type
  TIpv4Address = record
  strict private
    FAddress: TIpv4Quad;
    FMask: TIpv4Quad;
  private
    class function CreateInternal(const IP_ADDR_STRING: _IP_ADDR_STRING): TIpv4Address; static;
  public
    class function Create(const IP_ADDR_STRING: _IP_ADDR_STRING): TIpv4Address; static;
    class function Count(const IP_ADDR_STRING: _IP_ADDR_STRING): Integer; static;
    property Address: TIpv4Quad read FAddress;
    property Mask: TIpv4Quad read FMask;
  end;

  TIpv4AddressList = array of TIpv4Address;

  TIpv4AddressHelper = record helper for TIpv4Address
    class function CreateList(const IP_ADDR_STRING: _IP_ADDR_STRING): TIpv4AddressList; static;
  end;

Вы используете это так:

function TAdapterInfo.GetIpAddressList: TIpv4AddressList;
begin
  Result := TIpv4Address.CreateList(AdapterInfos.IP_ADAPTER_INFO[Index].IpAddressList);
end;

- Йерун

...