Constructor good for loading file contents?

  • Thread starter Thread starter Gustaf Liljegren
  • Start date Start date
G

Gustaf Liljegren

This may be a question of taste, but if there is a best practice, I want
to know. I have two choises:

SomeClass s = new SomeClass(file); // Load the file

or

SomeClass s = new SomeClass();
s.Load(file); // Load the file

The object 's' is constructed from contents of a file (or maybe a
stream). Is the contructor the natural place for reading file/stream
contents into an object, or is it better done separately, in a method?

I can think of one case when there's a need for a separate Load()
method. It's when you need to change properties of the object before
feeding data into it, like in:

XmlDocument x = new XmlDocument();
x.EntityResolver = null;
x.Load(file);
 
I guess it has to do more with what a class does. If your object manipulates
the same file through its existence, then put it in the constructor. After
all, constructor is where you "construct" your object -- where you
initialize the member variables, etc.
 
Gustaf Liljegren said:
SomeClass s = new SomeClass(file); // Load the file
or
SomeClass s = new SomeClass();
s.Load(file); // Load the file

If your object is meaningless without a file loaded into it, make the
filename a parameter to the constructor. If you could feasibly do
something with the object *without* it having a file loaded, just give
it the Load method. (Of course, you could still have the extra
constructor for anyone who wants to open a file automatically.)

P.
 
Gustaf said:
SomeClass s = new SomeClass(file); // Load the file
or
SomeClass s = new SomeClass();

As Paul explained, the choice of whether to include a no-argument
constructor depends on whether meaningful operations can be done on an
object constructed in such a manner. If every method throws an exception
until the Load call is made, for example, it's better to make it a
constructor so these errors cannot occur.
I can think of one case when there's a need for a separate Load()
method. It's when you need to change properties of the object before
feeding data into it, like in:

XmlDocument x = new XmlDocument();
x.EntityResolver = null;
x.Load(file);

Actually, in this case it may be better to supply a set of initial
properties to the constructor, in addition to the filename. You can wrap
these in an object which had the default values by default:

XmlDocumentProperties p = new XmlDocumentProperties();
p.EntityResolver = null;
XmlDocument x = new XmlDocument(file, p);

Now you can use custom properties as well as prevent the document from
being used without a file being specified.
 
Everyone has a different style.

I prefer to not perform any actions that might throw an exception in a ctor.
I use a Create/Load design (a two phase construction), where all the ctor
does is set state fields to known values, and a separate method performs the
operation. This makes cleanup logic much easier to implement and avoids side
effects. For example, if a static ctor throws an exception it renders that
type unusable for the life of the appdomain.

It also avoids ctors that take a l-o-n-g time to execute (which can create
its own set of problems). For example, what if the file is located on a
network where you are having intermittent connection problems? I prefer to
minimize my headaches by isolating operations. I pass arguments to ctors
when these values become part of the intial state of the object, not because
they force it to start an operation.

I recognize that many other people prefer doing it the other way...aint
choice grand.
 
Back
Top