Object parameter is nil, can't determine why

Viewed 322

I figure this should be pretty straight forward, but I have no idea why this is not working.

I've taken over legacy code and some of the objects used in a dll are, well, becoming unmanageable. Several objects have the same procedure

SetPropertyValue(propName,propValue:string);

Now, these methods are basically giant if..else statements that check the propName and assign the propValue if it matches the objects property:

if propName='name' then
  name:=propValue
else if propName='address' then
  address:=propValue

And so on.

Each time an object gets a new property (or a property type changes and therefore the value parameter being passed in needs to be cast differently), this method needs updating - obviously a chore that shouldn't need to be.

I've opted to write a global method to set an objects property that is dynamic and should need minimal maintenance.

Here is an short example of what I am doing so far. There are two units, Obj and Main - where Main is a VCL form with 2 edit boxes and a button, I am using button click to trigger the SetPropertyValue:

Obj

unit Obj;

interface

uses
  RTTI;

{$RTTI INHERIT}
type TmyObj = class(TObject)
  Name:String;
  Address:String;
  City:String;

  procedure SetPropertyValue(sPropName, sPropValue:String);
end;


procedure SetObjProperty(AObject : TObject; propName, propValue:String);

implementation

procedure SetObjProperty(AObject : TObject; propName, propValue:String);
var
  context:TRttiContext;
  rt: TRttiType;
  prop: TRttiProperty;
begin

  if not Assigned(AObject) then
    exit;

  context:=RTTIContext.Create;
  rt:=Context.GetType(AObject.ClassType);

  for prop in rt.GetProperties do
  begin

  //do some stuff 

  end;

  Context.Free;

end;

{ TmyObj }

procedure TmyObj.SetPropertyValue(sPropName, sPropValue: String);
begin
  SetObjProperty(self, sPropName, sPropValue);
end;

end.

Main

unit Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    edtPropName: TEdit;
    Label1: TLabel;
    edtPropValue: TEdit;
    btnGo: TButton;
    procedure btnGoClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  Obj;

{$R *.dfm}

procedure TForm1.btnGoClick(Sender: TObject);
var
  myObj:TMyObj;
begin

  myObj:=TMyObj.Create;
  myObj.SetPropertyValue(edtPropName.Text, edtPropValue.Text);

end;

end.

Rather than change the obj.SetPropertyValue (because I would have to change it over and over again in code), I just referenced the new procedure.

Unfortunately, no matter how I try to reference the object in Obj.SetPropertyValyue it is always empty in SetObjectProperty - so the rt is always empty and the loop doesn't do anything.

I know when passing an object, we are just passing a pointer, so even though I change the argument type to CONST, I still get the same empty/nil value when I enter the new procedure.

Any thoughts on what I have down wrong? I've even tried referencing SetObjProperty outside of the unit, so:

thisObj:=TMyObj.Create;
SetObjProperty(thisObj,sThisName, sThisValue);

But I still end up with the same nil obj in my new method.

Any and all help would be appreciated!

1 Answers
Related