Class Constructors

G

Guest

I have a class which defines multiple overloaded constructors. Within the
class methods is there a elegant way to determine which constructor was used
to instantiate the class (without setting flags in the constructor)?
 
L

Larry Lard

Samudra said:
I have a class which defines multiple overloaded constructors. Within the
class methods is there a elegant way to determine which constructor was used
to instantiate the class (without setting flags in the constructor)?

It shouldn't matter. All the constructors should leave the object in a
valid state to do whatever it needs to do. If you really need to do
this, it's either bad design or ... well, I don't know.

Show us some code?
 
D

David Browne

Samudra said:
I have a class which defines multiple overloaded constructors. Within the
class methods is there a elegant way to determine which constructor was
used
to instantiate the class (without setting flags in the constructor)?

The fact that you care which constructor is called probably indicates a
design problem. After each constructor is run the object should be in its
initial working state, and there should normally be no way to tell, or
reason to care what constructor was used.

David
 
D

Damien

Samudra said:
I have a class which defines multiple overloaded constructors. Within the
class methods is there a elegant way to determine which constructor was used
to instantiate the class (without setting flags in the constructor)?

In general, no. The behaviour of a class should be influenced by it's
functions, it's properties, and arguments passed to it's constructors
or functions. Not as a side effect of how the object was constructed.

If you need it's behaviour to be different, then make that explicit by
exposing an argument to the constructor, to ask for this different
behaviour.

About the only way your request might make sense is if there are a
mixture of private and public constructors, and you need different
behaviour if one of you're private constructors has been called. About
the only thing to do in this case would be to set a flag (which you've
stated a preference away from).

The simple reason for this? The vast majority of people do not want or
need to know which constructor was used. If this information was to be
automatically available, it would incur additional overhead for
everyone using the framework who does not need this information. It's
the same reason, for instance, that you cannot easily find out when an
object was constructed - unless you explicitly store that information
yourself within the constructor.

Damien
 
S

sloan

I concurr with the others.

I actually try to use 1 "main" constructor, and pass default values to it..
via other constructors.
(see below)

If you're tracking which contructor is called, you're doing something fudgy.
An object is supposed to exist on its own.

public class Emp

{

private string m_fname;

private string m_lname;

private bool m_isNew = true; //to show that the default falses work

public Emp () : this("defaultFirst","defaultLast",false)

{

}



public Emp (string fName, string lName, bool isNew)

{

this.m_fname = fName;

this.m_lname = lName;

this.m_isNew = isNew;

}

//then... if I have a constructor that doesnt have "isNew".. I do it like
this

public Emp (string fName, string lName) : this (fName,lName,false)

{


}

public void ReportVariables()

{

string x = this.m_fname.ToString() + System.Environment.NewLine;

x += this.m_lname.ToString() + System.Environment.NewLine;

x += this.m_isNew .ToString() + System.Environment.NewLine;

Console.WriteLine(x);

}

}





// How To Use



Emp e1 = new Emp();

e1.ReportVariables();

Emp e2 = new Emp("john" , "smith");

e2.ReportVariables();

Emp e3 = new Emp("mary", "jones", true);

e3.ReportVariables();
 
G

Guest

Thanks for your inputs. What I am trying to do is quite simple. I have a
stongly typed collection class, which can be instantiated though different
constructors -

public MetaFieldCollection()
{}
public MetaFieldCollection(int elementID)
{}
public MetaFieldCollection (ElementType elemType)
{}

On first access, I lazy load the collection. Now, I also want to define a
Refresh() Method, which will reload the collection. Of course, this means I
need to know how the class was instantiated. One way I can do this is by
checking whether elementID is set or elementType is set, which in itself is
not an issue but I was wondering if there was a more direct mechanism - hence
the question.

I understand from Damien's reply why there is no direct mechanism. But would
you guys say now also that the reason I need to know how my collection was
instantiated is not justified and implies bad design?
 
J

Jon Skeet [C# MVP]

Samudra said:
Thanks for your inputs. What I am trying to do is quite simple. I have a
stongly typed collection class, which can be instantiated though different
constructors -

public MetaFieldCollection()
{}
public MetaFieldCollection(int elementID)
{}
public MetaFieldCollection (ElementType elemType)
{}

On first access, I lazy load the collection. Now, I also want to define a
Refresh() Method, which will reload the collection. Of course, this means I
need to know how the class was instantiated. One way I can do this is by
checking whether elementID is set or elementType is set, which in itself is
not an issue but I was wondering if there was a more direct mechanism - hence
the question.

I understand from Damien's reply why there is no direct mechanism. But would
you guys say now also that the reason I need to know how my collection was
instantiated is not justified and implies bad design?

It sounds like you could do with a base class and two or three derived
classes, each of which knew how to load their data in a different way.

Currently, if someone instantiates the class using elemType, the
elementID member is useless, and vice versa. That doesn't necessarily
mean it's a bad design, but it's at least "smell" suggesting it's
perhaps not quite right.
 
N

Nick Hounsome

Jon Skeet said:
It sounds like you could do with a base class and two or three derived
classes, each of which knew how to load their data in a different way.

Currently, if someone instantiates the class using elemType, the
elementID member is useless, and vice versa. That doesn't necessarily
mean it's a bad design, but it's at least "smell" suggesting it's
perhaps not quite right.

I agree with John but another alternative is to store a delegate to handle
Refresh.
 
J

Jon Skeet [C# MVP]

Nick Hounsome said:
I agree with John but another alternative is to store a delegate to handle
Refresh.

That has a *lot* of appeal - partly because you wouldn't actually need
to keep hold of the elementId etc in the class itself, if you use an
anonymous method which will capture the parameter value from the
constructor.

I like it :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top