Как получить информацию о типе записи по ее указателю в Delphi XE? - PullRequest
2 голосов
/ 19 октября 2011

Если у меня есть TList со множеством указателей разных типов записей, как мне получить доступ к значениям разностных записей в TList?

Есть ли какой-нибудь способ получить тип записи или информацию о типе упомянутых записей?

В настоящее время я использую Delphi XE.

Ответы [ 4 ]

6 голосов
/ 19 октября 2011

Вашим разным типам записей нужен общий заголовок.Затем вы можете вначале привести указатели элементов списка к этому типу заголовка, чтобы определить, какой тип записи следует преобразовать в следующий.Например:

type
  TRecType = (recA, recB, recC);

  PRecHeader = ^TRecHeader;
  TRecHeader = record
    RecType: TRecType;
    ...
  end;

  PRecordA = ^TRecordA;
  TRecordA = record
    Header: TRecHeader;
    IntValue: Integer;
  end;

  PRecordB = ^TRecordB;
  TRecordB = record
    Header: TRecHeader;
    StrValue: String;
  end;

  PRecordC = ^TRecordC;
  TRecordC = record
    Header: TRecHeader;
    DblValue: Double;
  end;

var
  PRec: Pointer;
begin
  PRec := List[Index];
  case PRecHeader(PRec)^.RecType of
    recA: use PRecordA(PRec)^.IntValue as needed ...
    recB: use PRecordB(PRec)^.StrValue as needed ...
    recC: use PRecordC(PRec)^.DblValue as needed ...
  end;
end;
3 голосов
/ 19 октября 2011

Вы действительно не можете сделать это таким образом. В отличие от объектов Delphi, записи не несут с собой никаких RTTI. Если вы смешиваете кучу фрагментов данных разных типов и хотите выяснить, к какому типу данных они относятся во время выполнения, лучше всего просто использовать объекты, которые наследуют TObject.ClassType, и несколько других процедур для упрощения этой задачи.

Если вам действительно необходимо использовать записи по какой-либо причине, вам придется начинать каждую запись с пользовательского тега, который не изменяется. Я собирался описать систему, но похоже, что Реми опередил меня. Но это сопряжено с достаточными накладными расходами, что, опять же, вы можете просто использовать вместо этого объекты, так как, как только вы идете очень далеко по этому пути, вы в основном переопределяете много TObject в любом случае.

1 голос
/ 19 октября 2011

Как насчет использования стиля pascal объекта с {$ M +} ?. Это исключит накладные расходы на TObject

{$M+}

TRecordA = object
end;

TRecordB = object
end;

{$M-}
1 голос
/ 19 октября 2011

Я бы настоятельно рекомендовал использовать объект TObjectList из устройства Contnrs.(Это все еще существует в Delphi XE?) Это основано на TList, но вам нужно предложить TObject ссылки вместо указателей.Это небольшая разница, но она позволяет вам напрямую использовать операторы is и as для элементов списка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...