Delphi AV при использовании TStringList в пользовательском классе - PullRequest
0 голосов
/ 11 апреля 2020

В Delphi Рио я создал класс, целью которого является чтение записи из базы данных. Эта запись предназначена только для чтения, и после чтения мне нужно получить некоторые дополнительные свойства. Моя проблема связана со списком строк, который я хочу использовать в своем определении класса. У меня есть личный участник класса fVENDORS_TO_COLORCODE. Это строка, разделенная запятыми. Я хочу создать свойство, которое является списком TStringlist. Я использую TStringList.CommaToText для загрузки моего значения в Tstringlist. Я делаю это в конструкторе создания. У меня проблема в том, что хотя StringList допустим в конструкторе, он равен нулю за пределами конструктора, и я не знаю, что я делаю неправильно. Вот соответствующие части кода.

type
  TProfileDef = class(TObject)
  private
    fNAME: String;   
    fVENDORS_TO_COLORCODE: String;  // incoming comma separated string. Example string:  Microsoft,IBM
    fVENDORS_TO_COLORCODE_SL : TStringList;
    ..

  public  
    constructor Create(ProfileName: String); 
    destructor Destroy; override;   
  published   
    property NAME: String read fNAME;  
    property VENDORS_TO_COLORCODE: String read fVENDORS_TO_COLORCODE;
    property VENDORS_TO_COLORCODE_SL : TStringList read fVENDORS_TO_COLORCODE_SL;  
    ..
  end;

implementation

destructor TProfileDef.Destroy;
begin
inherited;
  fVENDORS_TO_COLORCODE_SL.Free;
end;


constructor TProfileDef.Create(ProfileName: String);
var
  fVENDORS_SL: TStringList;
  fVENDORS_TO_COLORCODE_SL: TStringList;
  TempVendorList : String;

begin
inherited Create;
fName := ProfileName;

.. [Find my record based on ProfileName, and load the DB columns into the private variables]..

    // Load the Color Code String into a StringList;
    fVENDORS_TO_COLORCODE_SL := TStringList.Create;   
    fVENDORS_TO_COLORCODE_SL.CommaToText :=  fVENDORS_TO_COLORCODE; 
end;

Внутри Конструктора создается список строк fVENDORS_TO_COLORCODE_SL и добавляются данные ... Проблема заключается в том, когда я пытаюсь использовать его ...

var
TestClass: TProfileDef;
begin
TestClass := TProfileDef.Create('Sample Profile');
// TestClass.Name is valid
// TestClass.VENDORS_TO_COLORCODE_SL is nil, and trying to access gives AV

Каким-то образом я определяю это неправильно, но я не могу определить, что это такое, чтобы исправить это.

Ответы [ 2 ]

5 голосов
/ 11 апреля 2020

У вашего класса есть приватное поле

fVENDORS_TO_COLORCODE_SL: TStringList;

Ваш конструктор должен создать объект TStringList и иметь эту переменную, указывающую на него. Я предполагаю, что это ваше намерение, по крайней мере. Однако ваш конструктор имеет локальную переменную с тем же именем , fVENDORS_TO_COLORCODE_SL, поэтому строка

fVENDORS_TO_COLORCODE_SL := TStringList.Create;  

действительно создает объект TStringList, но указатель сохраняется к этой локальной переменной , и поле класса с тем же именем остается nil.

Решение: Удалить объявление локальной переменной в конструкторе.

0 голосов
/ 11 апреля 2020
// Load the Color Code String into a StringList;
fVENDORS_TO_COLORCODE_SL := TStringList.Create;   

Эта строка в конструкторе является проблемой. У вас есть две переменные с именем fVENDORS_TO_COLORCODE_SL. Один из них является закрытым членом класса, объявленного в разделе private объявления класса, другой - локальной переменной, объявленной в разделе var конструктора.
Угадайте, какой из них имеет приоритет. Все верно, локальная переменная в конструкторе. Эта строка инициализирует локальную переменную с именем fVENDORS_TO_COLORCODE_SL, член частного класса с тем же именем по-прежнему nil. Как правило, я начинаю вводить локальные переменные в методе с l и только с предисловием членов класса с f, чтобы избежать именно такой проблемы. Переименуйте ваши локальные переменные в конструкторе следующим образом:

constructor TProfileDef.Create(ProfileName: String);
var
  lVENDORS_SL: TStringList;
  lVENDORS_TO_COLORCODE_SL: TStringList;
  lTempVendorList : String;
begin

Затем обновите ваш код и пересоберите. Все должно стать очевидным довольно быстро.

...