Какой оператор я перегружаю при назначении «Расширенной записи» нормальной переменной «Тип данных»? - PullRequest
4 голосов
/ 09 декабря 2011

Мне нужно знать, прежде всего, возможно ли то, что я пытаюсь сделать. Если это возможно, мне нужно знать, как.

Гораздо проще продемонстрировать проблему, чем объяснить ее, вот так:

У меня есть «Расширенная запись» (цель - хотя и не важная для этого вопроса - создать тип «Smart String» вместо обычного типа String):

TLKString = record
  Value: String;
  // Some methods here to operate on and build String values

  // Allows me to assign String values directly to "instances" 
  // of this record type! I have others (hence "overload") to 
  // handle other data types (such as Integer etc.)
  class operator Implicit(const AValue: String): TLKString; overload; 
end;

Теперь я могу использовать этот тип строки TLKS следующим образом:

var
  LSmartString: TLKString;
begin
  LSmartString := 'Hello World'; // The "Implicit" operator then 
                                 // assigns this to LSmartString.Value
end;

Хорошо, пока все отлично! Теперь мы подошли к проблеме ...

Мне нужно иметь возможность назначить значение LSmartString («экземпляр» TLKString) нормальной строковой переменной ...

var
  LSmartString: TLKString;
  LNormalString: String;
begin
  LSmartString := 'Hello World';

  // The next line works fine, but is not what I want!
  LNormalString := LSmartString.Value; 
  LNormalString := LSmartString; // E2010 (Incompatible Types)
end;

Здесь я отклеиваюсь, поскольку (я уверен, что вы заметите) последняя строка приведенного выше фрагмента приводит к E2010 Несовместимые типы: 'string' и 'TLKString' . Я, конечно, знал, что это будет так ... чего я не знаю, возможно ли преодолеть перегрузку оператора в типе моей записи TLKString, и если да, то какой оператор мне нужно перегрузить, чтобы сделать это.

Если это невозможно, то мне кажется немного глупым из CodeGear и Embarcadero иметь операторы Implicit и Explicit для обработки присвоения значений расширенному типу записи, но нет оператора для обработки обратного .

1 Ответ

6 голосов
/ 09 декабря 2011

Хорошо, я сам ответил на это ... и это было то, что я бы назвал "ослепительно очевидным".

Вот решение (в интересах других)

TLKString = record
  Value: String;
  // Some methods here to operate on and build String values
  class operator Implicit(const AValue: String): TLKString; overload; // handles String to TLKString assignment
  class operator Implicit(const AValue: TLKString): String; overload; // handles TLKString to String assignment! THIS IS THE ANSWER!
end;
...