Можно ли использовать два типа записей для типа строки?

Я создал этот помощник, чтобы добавить еще несколько функций в тип string:

type
  AStringHelper = record helper for string
    function Invert: string; overload;
    function InvertMe: string; overload;
  end;

Но когда я использую его в своем коде, TStringHelper in System.StrUtils "выходит", и я не могу использовать его функции.

Возможно ли, чтобы они оба сосуществовали?

Ответ 1

Максимум один помощник может работать в любой точке вашего кода. В документации говорится об этом:

Вы можете определить и связать несколько помощников с одним тип. Однако в любом случае применяется только нуль или один помощник. конкретное местоположение в исходном коде. Помощник, определенный в будет применяться ближайший к нему диапазон. Класс или область хранения справки определяется в обычном режиме Delphi (например, справа налево в блоке используется предложение).

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

Ответ 2

Простым решением этого может быть:

type
  TStr = record
  private
    FStr:string;
  public
    function Invert: string; overload;
    function InvertMe: string; overload;
  end;

При использовании литья типов вы можете получить доступ к функциям на TStr для обычной переменной string:

var
  s1,s2:string;
begin
  s1:='123456';
  s2:=TStr(s1).invert;
end;

Но, конечно, тогда мы можем спросить: почему бы просто не написать обычную функцию?: -)

В любом случае, мне нравится этот синтаксис class/object/record лучше, чем традиционная функция/процедура.

Ответ 3

Попробуйте создать свой собственный класс и помощник

TMyString = type string;
TMyStringHelper = record helper for TMyString 
  function Invert: TMyString; 
  function ToString: string;
end;

Используйте TMyString вместо String.

Чтобы использовать стандартные хелперы String, переносите переменную TMyString с помощью String() или используйте метод ToString.

var
  S1: TMyString;
  S2: String;
begin
  S1 := ' 123456 ';
  S1.Invert;
  S2 := String(S1).Trim;
  S2 := S1.ToString.Trim;
end;

Ответ 4

Другая возможность - использовать опцию "Список предков", предложенную помощниками.

Syntaxis:

type
identifierName = class|record helper [(ancestor list)] for TypeIdentifierName
  memberList
end;

И используйте так:

Unit1:   
THelperBase = Class helper for TMyClass
Public
  Function SayHello;
end;

Unit2:
Uses Unit1;
THelperChild = Class helper (THelperBase) for TMyClass
Public
  Function SayGoodBye;
end;

И, наконец, в вашем коде:

Uses Unit2;   

Var MyClass: TMyclass;   

MyClass:= TMyclass.Create;
MyClass.SayHello; //valid
MyClass.SayGoodBye; //valid

Ответ 5

"Список предков" работает ТОЛЬКО для классов, а не для записей, и, поскольку (Delphi- "идиоты"), где он идет вразрез, имеет собственную политику, утверждая:

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

И что именно они сделали с String-помощниками самим собой???? → FAIL !!!

Из-за этого вы должны выполнять приведение типов каждый раз, когда вам нужно вызывать собственное расширение строки, если вы делаете свой собственный помощник по записи для внутренних типов, таких как строка. По умолчанию в хелпере строковых записей много божьего материала!

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

Компилятор в порядке с помощниками записи, но отладчик/редактор отстой !!!

Хотел бы Delphi исправить это в ближайшее время