Как получить «помог» класс из функции вспомогательного класса? - PullRequest
3 голосов
/ 31 января 2020

Я пытаюсь написать вспомогательную функцию класса без статической ссылки на класс справки:

  TMyEnum = (meA, meB, meC);
  TMyEnumHelper = record helper for TMyEnum
  public
    class function InRange(AValue : integer) : Boolean; static;
  end;

...

class function TMyEnumHelper.InRange(AValue : Integer) : Boolean;
begin
  Result := (
    (AValue >= Ord(Low(TMyEnum))) and
    (AValue <= Ord(High(TMyEnum)))
  );
end;

Есть ли способ динамически получить класс справки? Я имею в виду что-то вроде следующего кода:

class function TMyEnumHelper.InRange(AValue : Integer) : Boolean;
begin
  Result := (
    (AValue >= Ord(Low(HelpedClass))) and
    (AValue <= Ord(High(HelpedClass)))
  );
end;

Я пытался использовать Self, но Delphi говорит E2003 Undeclared identifier: 'Self'

1 Ответ

3 голосов
/ 31 января 2020

Stati c методы класса не имеют параметра "self". Они также не могут получить доступ ни к каким членам экземпляра. (Они по-прежнему имеют доступ к полям класса, свойствам класса и методам класса.)

В этом случае (помощник является помощником записи), метод класса должен быть объявлен как stati c.

Как указывает @David, обычный метод класса (не stati c) может ссылаться на свой тип с помощью клавиши «Self», но только когда он ссылается на класс.
Пример:

type
  TMyClass = class
  end;
  TMyClassHelper = class helper for TMyClass   
     class function NameOfClass : String;
  end;

class function TMyClassHelper.NameOfClass : String;
begin
  Result := Self.ClassName;
end;

Если перечисление является смежным, вы можете использовать универсальный «вспомогательный» метод для получения диапазона с использованием RTTI.

type  
  TRttiHelp = record
    class function EnumInRange<TEnum>(AValue: Integer) : Boolean; static;
  end;

class function TRttiHelp.EnumInRange<TEnum>(AValue: Integer) : Boolean;
var
  typeData: PTypeData;
begin
  if GetTypeKind(TEnum) <> tkEnumeration then
    raise EInvalidCast.CreateRes(@SInvalidCast);

  typeData := GetTypeData(TypeInfo(TEnum));
  Result := (AValue >= typeData.MinValue) and (AValue <= typeData.MaxValue);
end; 

type
  TMyEnum = (a,b,c); 
begin
  WriteLn(TRttiHelp.EnumInRange<TMyEnum>(2));  // Writes true
end. 
...