2016-03-08 3 views
0

Я начал использовать много дженериков, но теперь мне становится сложнее и сложнее отлаживать, чтобы знать, на каком массиве на самом деле начинают работать. Смотрите пример:Как увидеть имя Generic Array во время отладки?

Type 
    TData = record 
     DataID:integer; 
     DataName:string; 
    end; 

var DataArr1,DataArr2,DataArr3:TArray<TData>; 

procedure WorkOnData(Data:TArray<TData>); 
begin 
    if Data = DataArr1 then // <-- PARKING HERE ON DEBUG I CAN SEE ARRAY DATA, BUT NOT WHICH ARRAY IT IS 
    ProcessA(DataArr1) 
    else if Data = DataArr2 then 
    ProcessB(DataArr2) 
    else if Data = DataArr3 then 
    ProcessC(DataArr3); 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    if Sender = Button1 then 
    WorkOnData(DataArr1) 
    else if Sender = Button2 then 
    WorkOnData(DataArr2) 
    else if Sender = Button3 then 
    WorkOnData(DataArr3); 
end; 

Таким образом, я могу определить массив путем сравнения, чтобы получить True/False:

Data = DataArr1 

, но это не дает мне информацию, которая массив это, перед сравнением. Таким образом, мне нужно было бы поставить точки останова после каждого сравнения, чтобы узнать, какой из них является Истиной.

Это, очевидно, не работает:

Data.Name 

TArray<Data>.Name 

Есть ли другой способ узнать, какой массив было принято, что я могу видеть в отладчике (Watch)?


Ответ/Решение:

Для всех, кто сталкивается с той же проблемой, вопрос: Как говорит Реми в общепринятом ответ, что я хотел бы достичь, не представляется возможным. Хорошо, теперь быстрое обходное решение - поставить сравнение (Data = DataArr1) в Watch и посмотреть, какой из них разрешен True. Не лучше, но все же можно использовать, так как теперь мы можем видеть, какой массив фактически используется.

+1

Этот код * не так *. Это неправильно делает ничего, а тем более использует дженерики. Правильному коду не нужно было бы использовать 'case' или' if' для перехода к другому коду; он будет использовать метод в базовом классе, который может быть переопределен в каждом подклассе для реализации определенного поведения. При использовании нескольких тестов вы победили всю цель использования дженериков. –

+1

'A: = TArray .Create (0); B: = A; 'Как называется массив, A или B? Массивы не имеют имен. Поведение переключения на идентичность массива кажется неправильным. Ваш настоящий код выглядит так. –

+0

Я действительно использую код, очень похожий. Я уменьшил количество методов, которые делают то же самое на разных массивах на 90%. Я сгруппировал массивы в самый общий массив и, поскольку они все одного типа, и используя TArray <>, теперь я могу называть единый метод для всех из них и просто применять разные коды к различным полям записи, а общие поля обрабатываются с помощью одного и того же кода. Прекрасно работает. –

ответ

3

После компиляции кода имена переменных отсутствуют. Когда вы отлаживаете WorkOnData(), единственным именем переменной, которое он может отобразить, является Data, и отладчик не знает, что указывает Data, не оценивая выражение, которое вы предоставляете. Так что нет, то, что вы просите, в принципе невозможно.

Что вам, вероятно, придется сделать, это обернуть массив внутри другого record, который имеет поле строки Name, а затем передать эту запись по мере необходимости. Когда вы проверите его в отладчике, вы увидите его значение Name.

+2

Если вы хотите идентифицировать эти массивы по имени, тогда да, дайте им имя. Тем не менее, очень вероятно, что дать им имя просто сделает ваш код громоздким и неуклюжим и не принесет никакой пользы. Поэтому, скорее всего, не делайте то, что говорит Реми в заключительном абзаце. Почти наверняка путь вперед будет заключаться в том, чтобы написать код, чтобы он не состоял из функции после функции, содержащей большие операторы if. После правильного кодирования кода вы не захотите связывать имя с каждым массивом. –

+0

Вопрос больше ориентирован на то, что мне неизвестно, и ничего не нашел, просматривая ресурсы. Я предполагаю, что ответ действительно нет - способ, которым я их сейчас настраиваю. Неважно, использование таких массивов перевешивает необходимость знать все детали при отладке. Есть обходной путь, я могу просто поместить сравнения в Watch и посмотреть, какой из них разрешен True: 'Data = DataArr1'. –

Смежные вопросы