In particular, I feel the need in TCharacter.IsLatin1
which is private
.
type
TCharacterHelper = class helper for TCharacter
public
class function IsLatin1(C: Char): Boolean; static; inline;
end;
class function TCharacterHelper.IsLatin1(C: Char): Boolean;
begin
Result := Ord(C) <= $FF;
end;
This one-liner method can be reimplemented in literally no time, but I'd better off leave the exact implementation details on the vendor's discretion.
Is there any way to "reintroduce" this method to public
visibility?
Is there any way to "reintroduce" this method to public visibility?
Yes. By introducing a non-static function call through a new class function.
The trick here is to use the helper ability to access all members through Self
. See Access a strict protected property of a Delphi class?
and How do I use class helpers to access strict private members of a class?
.
This is done by calling a private helper non-static function from the new class function, where Self
can be resolved.
Type
TCharacterHelper = class helper for TCharacter
private
class function IsLatin1Cracker(aChar: Char): Boolean; inline;
public
// Introduce a new public static class function
class function IsLatinOne(aChar: Char): Boolean; static; inline;
end;
class function TCharacterHelper.IsLatinOne(aChar: Char): Boolean;
begin
Result := IsLatin1Cracker(aChar);
end;
class function TCharacterHelper.IsLatin1Cracker(aChar: Char): Boolean;
begin
Result := Self.IsLatin1(aChar); // Here Self can access base class
end;
You cannot use the original method name though, but still the original class function can be called this way.
Oops, David showed a way to expand this idea to use the original name. That can be a versatile trick to have in the toolbox.
Just to refer to what documentation has to say about this:
Ordinary Class Methods
:
You can use Self to call constructors and other class methods, or to access class properties and class fields.
Class Static Methods
:
Unlike ordinary class methods, class static methods have no Self parameter at all.
Note: Records can only have static class methods, unlike classes.
Class and Record Helpers
:
You can use the helper any place where you can legally use the extended class or record. The compiler's resolution scope then becomes the original type, plus the helper.
...
The visibility scope rules and memberList syntax are identical to that of ordinary class and record types.
You can define and associate multiple helpers with a single type. However, only zero or one helper applies in any specific location in source code. The helper defined in the nearest scope will apply. Class or record helper scope is determined in the normal Delphi fashion (for example, right to left in the unit's uses clause).
As you noted above, records can only have static class methods. So if you wanted to "reintroduce" a private class method in a record, here is a solution (based on David's technique):
Suppose we have:
Type
TTestRec = record
private
class Function IsLatin1(C: Char): Boolean; static; inline;
end;
And add a helper in a new unit:
unit HelperUnitForTTestRec;
interface
Type
TTestRecHelper = record helper for TTestRec
public
class function IsLatin1(c:Char): Boolean; static; //inline; !! Inlining not possible
end;
implementation
Type
TTestRecCracker = record helper for TTestRec
private
function IsLatinOne(C:Char): Boolean; inline;
public
class function IsLatin1Cracker(c:Char): Boolean; static; inline;
end;
function TTestRecCracker.IsLatinOne(c: Char): Boolean;
begin
Result := Self.IsLatin1(C); // <-- Here is Self resolved
end;
class function TTestRecCracker.IsLatin1Cracker(c: Char): Boolean;
var
tmp: TTestRec;
begin
Result := tmp.IsLatinOne(C); // <-- Must use a call to ordinary method
end;
class function TTestRecHelper.IsLatin1(c: Char): Boolean;
begin
Result := IsLatin1Cracker(C);
end;
end.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With