简体   繁体   中英

Delphi AV when using TStringList in a custom class

In Delphi Rio, I have created a class whose purpose is to read a record from a database. This record is purely read only, and after reading, I need to derive some additional properties. My problem has to do with a Stringlist I am wanting to use in my class definition. I have a private class member called fVENDORS_TO_COLORCODE. This is a comma separated string. I am wanting to make a property that is a TStringlist. I am using TStringList.CommaToText to load my value into the Tstringlist. I do this in the Create Constructor. The issue I am having is that while the StringList is valid in the constructor, it is nil outside of the constructor, and I don't know what I am doing wrong. Here is the relevant portions of code.

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;

Within the Constructor, the fVENDORS_TO_COLORCODE_SL stringlist is created, and data is added... The issue is when I try to use it...

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

Somehow I am defining this wrong, but I can't determine what it is is, in order to correct it.

Your class has a private field

fVENDORS_TO_COLORCODE_SL: TStringList;

Your constructor should create a TStringList object and have this variable point to it. I assume that is your intention, at least. However, your constructor has a local variable with the same name , fVENDORS_TO_COLORCODE_SL , so the line

fVENDORS_TO_COLORCODE_SL := TStringList.Create;  

indeed creates a TStringList object, but the pointer is saved to this local variable , and the class's field with the same name remains nil .

Solution: Remove the declaration of the local variable in the constructor.

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

This line here in the constructor is the problem. You have two variables named fVENDORS_TO_COLORCODE_SL . One is a private member of the class declared in the private section of th class declaration, the other is a local variable declared in the var section of the constructor.
Guess which one takes precedence. That's right, the local variable in the constructor. That line initialized the local variable named fVENDORS_TO_COLORCODE_SL , the private class member with the same name is still nil . As a general rule I preface local variables in a method with an l and only preface class members with an f to avoid just this sort of problem. Rename your local variables in the constructor like so:

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

Then update your code and rebuild. Things should start to become obvious pretty quickly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM