Reputation: 3941
I read here it is possible to call another constructor Calling constructor from other constructor in same class
But it calls the other constructor at the beginning, whereas I want to call at the end. Is this possible ?
Update for people asking for specific: In program.cs I want to be able, depending on some context, to do
either this:
// Form1 will show a message from its own private member
Application.Run(new Form1());
or this:
// Form1 will show a message from class1 member (kind of overloading form1 message if class1 exists)
Application.Run(new Form1(new Class1()));
I Form1 I have
private string member = "Test Sample if no class1";
In class1 I have
private string member = "Test Sample from class1";
public string member;
{
get { return this.member; }
set { this.member = value; }
}
In Form1 I have these 2 constructors
// of course Form1() could contain 100 lines of code
Form1() { MessageBox.Show(this.member); }
// I don't want to duplicate 100 lines in second constructor
// so I need to call first constructor
Form1(class1) {
this.member = class1.member;
// this is where I would now like to call Form1()
// but the syntax below doesn't work
this();
}
Upvotes: 2
Views: 2115
Reputation: 22460
I don't see why the answers from people here can't be used in your case. And that does not rely on the complexity in your constructor.
There are 2 approaches you can use:
Perfect answer by Pavel Minaev that solves your problem by chaining constructors.
This approach can be used if your call is not "in the middle" of something.
Perfect answer by Christian Hayter that solves your problem by moving common initializing to a separate method that is called in all constructors. That way you can do whatever you like in the different constructors.
Upvotes: 0
Reputation: 273854
No, the constructor mechanism is very clear and strict, you can only 'call' an other constructor before the one you are writing.
But you could use that to your advantage, just reverse your thinking (approach) to make the 'last' constructor the one the user calls. To work out the specifics, you will have to post some sample code.
There are easy workarounds, like:
class Form1
{
public Form1(Class1 c1)
{
if (c1 != null) this.member = c1.member;
}
public Form1() : this(null)
{
}
}
But you are not allowed to call a constructor form 'inside' another, this would create much more problems.
Upvotes: 7
Reputation: 31071
In the general case, no. It's not a feature supported either by the C# language or the CLR.
In your specific case, just follow the pattern Microsoft have already given you with the designer code. If it's good enough for them...
public Form1() {
InitializeComponent();
InitializeComponentEx();
MessageBox.Show(this.member);
}
public Form1(T class1) {
this.member = class1.member;
InitializeComponent();
InitializeComponentEx();
}
private void InitializeComponentEx() {
// my 100 lines of code
}
Upvotes: 2
Reputation: 2229
The shared logic is placed in the ConstructorFinished
method.
Form1() {
// Call the method to do the logic
ConstructorFinished();
}
void ConstructorFinished()
{
MessageBox.Show(this.member);
}
Form1(class1) {
this.member = class1.member;
// Call the method to do the logic
ConstructorFinished();
}
Upvotes: 2
Reputation: 101665
As others have already explained, this just isn't how it works. For your particular case, I would probably do this:
Form1() : this(null)
{
}
Form1(Class1 class1)
{
if (class1 != null)
{
this.member = class1.member;
}
...
MessageBox.Show(this.member);
...
}
Upvotes: 2
Reputation: 23375
The general solution for this is to put your standard initialisation code in a main constructor, then use the other constructors to pass into it. Since you're only setting a string, you'd do something like this:
private const string DefaultValue = "some default value";
private string member;
Form1() : this(DefaultValue)
{
}
Form1(string overloadedStringAhoy)
{
this.member = overloadedStringAhoy;
}
If you call the default constructor (Form1()) you will simply pass through to the overloaded constructor with a default value for the name.
I tend to avoid these kinds of constructors, as complicating them with "oh this has to happen in this order and that won't be set" logic can make maintenance harder. If you encounter this a lot, tread carefully. :)
In this case, it's a trivial setup and the code isn't going to get too complicated and it'll do what you need, so it's OK I guess. If you ever find yourself having to special case + pass through a lot of initialisation code, it's often a lot nicer to use a simple factory or builder class. This way, you keep your class constructor code as simple as possible and leave the wiring to the factory/builder.
Upvotes: 1
Reputation: 158409
Not that I am aware of. You should probably move the initialization code that you need to perform last into a separate, private method and have that called from both constructors where appropriate.
Upvotes: 12
Reputation:
No, if you use constructor chaining, the base class constructor is always called first.
Upvotes: 7