Sign in to follow this  

[.net] Ways around virtual method call in constructor?

This topic is 3780 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello there, is there some kind of solution to circumvent the virtual call in constructor problem? Specifically, I'd like to raise a sort of "Init" event after the type's constructor (and its base type's constructor) have run. But I cannot raise the OnInit event inside the constructor for that reason. I'd like for that event to fire as soon as the object is instantiated (after the type x = new type(..);) so that "on the next" line the control has everything it needs already created. The obvious solution would be for "someone else" to raise that event after the constructor is run, but it doesn't seem to be easy. So are there some other solutions for this problem or should I just axe this feature? :) Thanks in advance.

Share this post


Link to post
Share on other sites
Quote:
Original post by AvengerDr
Hello there,
is there some kind of solution to circumvent the virtual call in constructor problem? Specifically, I'd like to raise a sort of "Init" event after the type's constructor (and its base type's constructor) have run. But I cannot raise the OnInit event inside the constructor for that reason.

I'd like for that event to fire as soon as the object is instantiated (after the type x = new type(..);) so that "on the next" line the control has everything it needs already created. The obvious solution would be for "someone else" to raise that event after the constructor is run, but it doesn't seem to be easy. So are there some other solutions for this problem or should I just axe this feature? :)

Thanks in advance.


I suppose you could wrap the constructor call in a static method?

something like this:


class foo {
private:
foo() {/* do all the regular initialization */}
public:
static void CreateFoo() { foo f; f.FireInitEvent(); return f; }
};


Would that work?
What do you need it for, anyway? There might be better/simpler solutions.

Share this post


Link to post
Share on other sites
The 'virtual call in constructor' solution is to do everything that you would do in that overridden function in the constructor.

As for firing an event from the constructor - think about it, nothing could have hooked the event source if the object is not yet created.

If you always need to do something immediately after a class is completely constructed you might want a factory pattern of some sort.

(Edit) That static constructor wrapper would work, too, but you might want to make sure you aren't copy-on-returning the object. Ignore that problem if you're using C#.

Share this post


Link to post
Share on other sites
Well I'm creating a library of user interface controls useable in MDX projects (I'm considering a switch to SlimDX as soon as I fix some problems, though).

Ideally I'd wish to employ a uniform development pattern: ie all control initialization done in a "Init" method and so on. Unfortunately if I define an abstract protected virtual "Init" method in the base type I obviously cannot (well shouldn't) call it from the constructor. In that method I'd fire the OnInit event, but I can't do it for the above problem. I'd like not to have the user call the Init method himself because well.. it's not elegant enough :D And he could forget. In ASP.net there is some sort of Init event, but I guess it is called as soon as the XML parser reads objects from the ASPX file. The static constructor seemes a good idea, but again, ideally controls should be created as the windows forms designer does.

It's just a stylistic problem anyway :) I could define the Init method into an interface and have each deriving class define a 'new' method. But If I could have defined a protected virtual method I could have overriden the method, adding just the instructions needed by the deriving class instead of doing it all over again.

Share this post


Link to post
Share on other sites
You could do something like this.


class Base
{

public Base()
{

}

public virtual void Init()
{
System.Windows.Forms.MessageBox.Show("Base");
}
}

class Inherit :Base
{
public Inherit()
{
Init();

}

public override void Init()
{
System.Windows.Forms.MessageBox.Show("Inherit");
base.Init();
}
}




Does that do what you need it to?

theTroll

Share this post


Link to post
Share on other sites
Yes, that's exactly what I'd like to do, but calling a virtual method in the constructor (as the topic says) is apparently "a Bad Thing". It's not that it cannot be done, it is that it shouldn't be done, because when the base constructor calls the virtual method, the derived type has not yet been created (because the call happens in the base constructor, not even the base type could be fully created) so some problems could arise. That's why I was asking about this problem.

This is the situation:

the inheritance hierarchy is composed in this way:

BaseControl - basic functionality common to all controls
RenderableControl - functionality common to all controls that can be rendered (ie those made of "vertices")
"Real" Control: a Panel, Button, Checkbox, DropDownList, etc.

When a "real" control is created I send the information about the default text and control appearance "down" to the base constructors. A control appearance can set such properties as size, border style and so on. This causes the corresponding "SizeChanged" event (and others) to be raised. Obviously this is bad for the above reasons because we're still in a constructor. So right now I'm disabling event raising while in the constructor (controls have a "designMode" property that means that the User Interface has not been fully constructed yet).

My solution right now would be to leave the events disabled while in "DesignMode", "remember" the Textstyle and Controlstyle "class" (think of CSS class names) and use that information to automatically recover the corresponding style information when DesignMode becomes false. This could work but there's a small annoyance. My UI "declaration" is now similar to the automatically generated code of the windows forms designer. Something like this:


// Sets the interface in design mode.
hud.BeginDesign();

Button button = new Button();
button.Text = "This is a button";
button.Position = new Vector2(10,10);
button.Click += new (....);

hud.EndDesign();



Now if someone wants to access a control's "Textstyle" or "Controlstyle" property, before the EndDesign method is called, at that point the corresponding object won't have been created yet. So I'll have to check if they're null and create them on the fly in the getter.

The problem is that in the set DesignMode to false part (which will happen on hud.EndDesign() ), I won't know if those objects have or have not been created. So I'll have to recheck it again.

There should be some sort of "finally" keyword that could be attached at the end of constructors, to specify some method that automatically fires as soon as the constructor returns. Or is there some other way? I have looked at the Windows.Forms.Control source with a Reflector and they're checking to see if the "handle" is not null before raising events while in the constructor.

Any other ideas?

Share this post


Link to post
Share on other sites

This topic is 3780 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this