Как проверить содержимое неуниверсального TObjectList при отладке?

Обобщение:
1. Приведение типов вручную при отладке, как указали LachlanG и Кен.
2. Использование концепции визуализаторов отладчика, появившейся после Delphi 2010.
3. Переключение к дженерикам-аналогам.

=========================================

Возьмем, к примеру, следующий код:

Если точки останова установлены в конце TestRegular и в конце TestGenerics соответственно, можно увидеть элементы общего списка (и даже содержимое элементов) через инспектор отладки, но ничего значимого (даже количество ) для обычного списка объектов при наведении курсора мыши на переменную tmp. Мне интересно, есть ли способ добиться аналогичной функциональности времени отладки для обычного списка объектов?

    unit Unit2;

    interface

    uses
      Contnrs, Generics.Collections,
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;

    type
      TMyItem = class;
      TMyItemList = class;
      TForm2 = class;

      TMyItem = class
      private
        fname: string;
      public
        property name: string read fname;
        constructor Create(aName: string);
      end;

      TMyItemList = class(TObjectList)
      protected
        procedure SetObject (Index: Integer; Item: TMyItem);
        function GetObject (Index: Integer): TMyItem;
      public
        function Add (Obj: TMyItem): Integer;
        procedure Insert (Index: Integer; Obj: TMyItem);
        property Objects [Index: Integer]: TMyItem
          read GetObject write SetObject; default;
      end;

      TForm2 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
        procedure TestRegular;
        procedure TestGenerics;
      public
        { Public declarations }
      end;

    var
      Form2: TForm2;

    implementation

    {$R *.dfm}

    { TMyItem }

    constructor TMyItem.Create(aName: string);
    begin
      fname := aName;
    end;

    { TMyItemList }

    function TMyItemList.Add(Obj: TMyItem): Integer;
    begin
      Result := inherited Add (Obj);
    end;

    procedure TMyItemList.SetObject(Index: Integer; Item: TMyItem);
    begin
      inherited SetItem (Index, Item);
    end;

    function TMyItemList.GetObject(Index: Integer): TMyItem;
    begin
      Result := inherited GetItem (Index) as TMyItem;
    end;

    procedure TMyItemList.Insert(Index: Integer; Obj: TMyItem);
    begin
      inherited Insert(Index, Obj);
    end;

    {TForm2}

    procedure TForm2.FormCreate(Sender: TObject);
    begin
      TestGenerics;
      TestRegular;
    end;

    procedure TForm2.TestRegular;
    var
     tmp: TMyItemList;
    begin
     tmp := TMyItemList.Create;
     tmp.Add(TMyItem.Create('1'));
     tmp.Add(TMyItem.Create('2'));
     tmp.Free;
    end;

    procedure TForm2.TestGenerics;
    var
     tmp: TObjectList<TMyItem>;
    begin
     tmp := TObjectList<TMyItem>.Create;
     tmp.Add(TMyItem.Create('1'));
     tmp.Add(TMyItem.Create('2'));
     tmp.Free;
    end;

    end.

person SOUser    schedule 13.03.2011    source источник
comment
Должна быть возможность написать помощник отладчика или как-то так, чтобы он динамически запрашивал объект для его класса, а затем переходил к работе. Я бы просто перестал использовать нетипизированную версию. На самом деле у меня уже есть!   -  person David Heffernan    schedule 13.03.2011
comment
Большое спасибо за ваш комментарий! Не могли бы вы помочь упомянуть пример помощника отладчика?   -  person SOUser    schedule 13.03.2011
comment
Под In fact I already have! вы подразумеваете, что вы перешли на коллекции дженериков? Не могли бы вы поделиться своим мнением о спектакле?   -  person SOUser    schedule 13.03.2011
comment
производительность универсальной версии лучше, потому что нет динамического приведения.   -  person David Heffernan    schedule 13.03.2011
comment
Фактически это визуализатор отладчика.   -  person David Heffernan    schedule 13.03.2011


Ответы (2)


Я не думаю, что вы сможете улучшить то, что появляется в подсказке при наведении курсора мыши.

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

Например, вы можете привести переменную tmp к типу TObjectList(tmp) из Окна оценки (Ctrl F7) или создать Watch (Ctrl F5) для переменной типа.

person LachlanG    schedule 13.03.2011
comment
!LachlanG: Большое спасибо за ваш комментарий! Ты прав! Напишите TObjectList(tmp) в окне оценки, переключитесь на вкладку свойств, и я смогу получить количество. Не могли бы вы упомянуть, могу ли я также проверять элементы в обычном TObjectList? - person SOUser; 13.03.2011
comment
@Xichen Li - Просто измените свой тип в окне оценки на TMyItemList(tmp), и вы сможете ссылаться на отдельные элементы как TMyItemList(tmp)[0].Name и TMyItemList(tmp)[1].Name. Если это не сработает, наберите еще немного: TMyItem(TMyItemList(tmp).[0].Name. - person Ken White; 13.03.2011
comment
@Ken: Большое спасибо за ваше предложение! Он прекрасно работает с TMyItemList(tmp)[0].Name! - person SOUser; 13.03.2011

Существуют визуализаторы отладчика, позволяющие настраивать возможности визуализации отладчика. Я никогда не использовал их, но насколько я понимаю, вы можете комбинировать их с некоторым RTTI и давать более подробную информацию об экземпляре TObject.

Однако использование дженериков - это то, что вам нужно здесь. Это дает типизацию во время компиляции, что имеет явные преимущества. Я бы просто так сделал.

person David Heffernan    schedule 13.03.2011
comment
Большое спасибо за ваши предложения! - person SOUser; 13.03.2011
comment
Я пытался изучить Open Tools API для создания настраиваемых визуализаторов отладчика. Но, похоже, мне нужно создать его для каждого потомка Singlet TObjectList. Как вы сказали, дженерики, вероятно, лучший выбор. - person SOUser; 13.03.2011
comment
Я уверен, что это можно сделать один раз для TObjectList и позволить RTTI делать тяжелую работу. Но дженерики побеждают! - person David Heffernan; 13.03.2011
comment
Спасибо, что упомянули, что это можно сделать! Затем я должен попробовать это через некоторое время. - person SOUser; 14.03.2011