Конвертации это operator implicit
и operator explicit
:
type
t1=class
i:integer;
constructor(i:integer) :=
self.i := i;
class function operator implicit(i:integer):t1 := new t1(i);
class function operator implicit(a:t1):integer := a.i;
end;
begin
var i:integer := 5;
var a:t1;
a := i;//тут неявно преобразовывает
i := a;
a := t1(i); //тут явно преобразовывает
i := integer(a);
end.
type
t1=class
i:integer;
constructor(i:integer) :=
self.i := i;
class function operator explicit(i:integer):t1 := new t1(i);
class function operator explicit(a:t1):integer := a.i;
end;
begin
var i:integer := 5;
var a:t1;
//a := i;//тут неявно преобразовывает
//i := a;//не сработает, потому что explicit переводится "явно"
a := t1(i); //тут явно преобразовывает
i := integer(a);
end.
Их можно делать экстеншн методами:
function operator explicit(self:integer):string; extensionmethod := self.ToString;
function operator explicit(self:string):integer; extensionmethod := StrToInt(self);
begin
var i:integer := 5;
var s:string;
s := string(i);
i := integer(s);
end.
Ну и, конечно, никто не мешает делать разные названия (SToBInt
,SToInt
и т.п.).
Проблема одинаковых названий - в том что компилятору придётся магическим образом угадывать какой тип вы ходите. Вот смотрите:
var i := SToR('1234');
Какой тип должен быть у i
? Можно его, конечно, задать явно, но в таком случае выбор перегрузки будет зависеть от контекста вне функции (вне её параметров), что порождает кучу ошибок компилятора и помогает программисту делать глупые ошибки.
И, в конце концов, если вам не важна производительность - можете сделать SToR
шаблонной, и тогда писать SToR&<BigInteger>
, чтоб выбрать перегрузку для BigInteger
. Производительность будет ниже потому - что придётся выбирать тип в процессе выполнения а не компиляции.