How to combine reading and writing of properties in one procedure or function to simplify XML serialization

Viewed 117

I want to write and read some properties of an object to an XML file.

Therefore I would like to use a procedure which bundles the writing and reading so that I don't have to repeat the list of XML node paths and names (one for writing and one for reading):

type
  TXMLFileIO=class
  public
    FReadFromXMLFile: Boolean; 
    procedure WriteReadInteger(const APathOfTheParentNode: string; const ANodeName: string; var AValue: Integer);
    //other declarations
  end;

procedure TXMLFileIO.WriteReadInteger(const APathOfTheParentNode: string; const ANodeName: string; var AValue: Integer);
begin
  if FReadFromXMLFile then
  begin
    AValue:=GetXMLNodeIntegerValue(APathOfTheParentNode, ANodeName);
  end
  else
  begin
    AddXMLIntegerNode(APathOfTheParentNode, ANodeName, AValue);
  end;
end; 

This will not work since I cannot pass a property as var parameter in var AValue: Integer

I could use a function like

function TXMLFileIO.WriteReadInteger(const APathOfTheParentNode: string; const ANodeName: string; const AValue: Integer): Integer;
begin
  if FReadFromXMLFile then
  begin
    Result:=GetXMLNodeIntegerValue(APathOfTheParentNode, ANodeName);
  end
  else
  begin
    AddXMLIntegerNode(APathOfTheParentNode, ANodeName, AValue);
    Result:=AValue;
  end;
end; 

and call it like

  MyXMLFileIO.FReadFromXMLFile := true; {or false depending if we want to read or write}
  MyIntegerProperty1 := MyXMLFileIO.WriteReadInteger(Path1, Name1, MyIntegerProperty1);
  MyIntegerProperty2 := MyXMLFileIO.WriteReadInteger(Path2, Name2, MyIntegerProperty2);
  etc.

but this will set the property also when I write (which seems not elegant to me because it might cause problems depending on the setter method of the property).

Is there another better way to do this?

1 Answers

Passing a var param in order to retrieve a value could lead to side effects, so not a good idea.

It would be better to create separate read and write for the property.

type
  TXMLFileIO=class
  private
    property Propvalue: integer read ReadInteger write WriteInteger;
  public
    FReadFromXMLFile: Boolean; 
    function ReadInteger(const APathOfTheParentNode: string; const ANodeName: string): integer;
    procedure WriteInteger(const APathOfTheParentNode: string; const ANodeName: string; var AValue: Integer);
    //other declarations
  end;

procedure TXMLFileIO.ReadInteger(const APathOfTheParentNode: string; const ANodeName: string): integer;
begin
  result:=GetXMLNodeIntegerValue(APathOfTheParentNode, ANodeName);
end;

procedure TXMLFileIO.WriteInteger(const APathOfTheParentNode: string; const ANodeName: string; var AValue: Integer);
begin
  AddXMLIntegerNode(APathOfTheParentNode, ANodeName, AValue);
end; 

I cant make comments so posting as an answer.

Related