Как преобразовать имя класса в виде строки в класс?

У меня есть имена классов в списке строк. Например, это может быть «TPlanEvent», «TParcel», «TCountry» и т. д.

Теперь я хочу узнать размеры, зациклив список.

Это работает, чтобы иметь:

Size := TCountry.InstanceSize;

Но я хочу так:

for i := 0 to ClassList.Count - 1 do
  Size := StringToClass(ClassList[i]).InstanceSize;

Очевидно, мой вопрос заключается в том, что написать вместо метода StringToClass, чтобы преобразовать строку в класс.


person Roland Bengtsson    schedule 28.04.2010    source источник


Ответы (4)


Поскольку вы используете список строк, вы также можете хранить там классы:

var
  C: TClass;

  StringList.AddObject(C.ClassName, TObject(C));

...

for I := 0 to StringList.Count - 1 do
  Size := TClass(StringList.Objects[I]).InstanceSize;

...

person Ondrej Kelle    schedule 28.04.2010
comment
это, конечно, работает только в том случае, если OT сам заполняет список, а не в том случае, если этот список, например, читается из файла или что-то в этом роде... - person Oliver Giesen; 28.04.2010

Если ваши классы являются производными от TPersistent, вы можете использовать RegisterClass и FindClass или GetClass . В противном случае вы могли бы написать какой-то механизм регистрации самостоятельно.

person Uli Gerhardt    schedule 28.04.2010

В Delphi 2010 вы можете использовать:

function StringToClass(AName: string): TClass;
var
  LCtx: TRttiContext;
  LTp: TRttiType;
begin
  Result := nil;

  try
    LTp := LCtx.FindType(AClassName);
  except
    Exit;
  end;

  if (LTp <> nil) and (LTp is TRttiInstanceType) then
    Result := TRttiInstanceType(LTp).Metaclass;
end;

Одна нота. Поскольку вы сохраняете в списке только имена классов, этот метод не будет работать, поскольку TRttiContext.FindType ожидает полное имя типа (например, uMyUnit.TMyClass). Исправление состоит в том, чтобы прикрепить модуль, в котором вы храните эти классы, в цикле или в списке.

person alex    schedule 28.04.2010
comment
К сожалению, я использую Delphi 2007 - person Roland Bengtsson; 28.04.2010

  1. Вы должны использовать FindClass, чтобы найти ссылку на класс по его имени. Если класс не найден, будет возбуждено исключение.
  2. При желании вы должны вызвать RegisterClass для своих классов, если они не указаны явно в коде.
person da-soft    schedule 28.04.2010