Как определить неявные операторы преобразования для взаимозависимых записей?
Я использую перегрузку оператора для записей в 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;
Ответы
Ответ 1
У вас не может быть передовых объявлений для типов записей. Определите оба оператора 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 (или наоборот).
Ответ 2
Возможно, вы сможете сделать это с помощью помощников записи.
Ниже приведено то, что я недавно сделал, чтобы обойти невозможность записи декларации 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;
- Йерун