The importance of the right 'entry point' when adding your class inC# Form constructor

R

raylopez99

Oh, I know, I should have provided complete code in console mode
form. But for the rest of you (sorry Jon, just kidding) I have an
example of why, once again, you must pick the correct entry point in
your code when adding a class (oops, I meant variable, or
instantiation of a object that's a class) to a form constructor.

Specifically, adding a class variable should always come BEFORE the
statement "InitializeComponent()" in your form constructor.

Consider this example (WRONG WAY):

public partial class Form2 : Form
{
Class001 MyClass001; //must be declared here--but that's not
the point of this thread

public Form2()
{

//myClass001 = new Class001(); // MUST BE PUT HERE, BEFORE
InitializeComponent!
InitializeComponent();

myClass001 = new Class001(); //WRONG! DO NOT PLACE
AFTER! GET RUNTIME ERROR!
}

// stuff deleted

private void splitContainer1_Panel1_Resize(object sender, EventArgs e)
{
myClass001.SomeMemberFunction(); //RUN-TIME ERROR! THIS IS
NULL SINCE myClass001 DOES NOT EXIST!!!
}

//end

If you place the variable (instantiated object) myClass001 after
"InitializeComponent()" the program will likely not work, because the
splitContainer control object actually gets fired up or instantiated
*before* the Form2 (subform to Form 1) default constructor does.
Don't ask me why, but that's what happens. Hence
myClass001.SomeMemberFunction() = null, and you'll get a run-time
exception. Placing the instantiation of myClass001 = new Class001();
before InitializeComponent(); however, solves this problem.

Another example of having to correctly pick the right 'entry point'
for something.

And btw you won't find this error in "Console Mode". Sorry Jon! ;-)

RL
 
J

Jon Skeet [C# MVP]

raylopez99 said:
Oh, I know, I should have provided complete code in console mode
form. But for the rest of you (sorry Jon, just kidding) I have an
example of why, once again, you must pick the correct entry point in
your code when adding a class (oops, I meant variable, or
instantiation of a object that's a class) to a form constructor.

Specifically, adding a class variable should always come BEFORE the
statement "InitializeComponent()" in your form constructor.

That's true if any of the events which get fired during initialization
rely on that variable, yes.
Another example of having to correctly pick the right 'entry point'
for something.

And btw you won't find this error in "Console Mode". Sorry Jon! ;-)

You can see exactly the same effect in a console app.
InitializeComponent() tends to do more than you'd do in a non-GUI
constructor, particularly around firing events, but there's nothing
GUI-specific going on in terms of the language here. It's just that
InitializeComponent happens to fire some events after subscribing to
them.

Here's an example of a console app which similarly dies (although on a
threadpool thread, so the process just gets torn down):

using System;
using System.Threading;

class ConsoleApp
{
string name;
Timer timer;

public ConsoleApp()
{
InitializeSomething();
name = "Jon";
}

void InitializeSomething()
{
timer = new Timer(DisplayNameLength);
timer.Change(500, Timeout.Infinite);
// Wait for the timer to fire...
Thread.Sleep(1000);
}

void DisplayNameLength(object state)
{
Console.WriteLine ("The length of the name is... {0}",
name.Length);
}
}

class Program
{
static void Main()
{
new ConsoleApp();
}
}
 
R

raylopez99

[stuff about console mode]

Thanks Jon. What I found strange was that a split container would get
initialized /worked on by the compiler/interpreter/runtime engine
before the form that contains the split container. That was
unexpected. To get around this problem, I simply moved the variable
that I needed before the statement InitializeComponent();

To me it shows that you have to be careful where you insert your
classes...but that's too general a statement to be of much use, I
admit.

RL
 
J

Jon Skeet [C# MVP]

raylopez99 said:
[stuff about console mode]

Thanks Jon. What I found strange was that a split container would get
initialized /worked on by the compiler/interpreter/runtime engine
before the form that contains the split container. That was
unexpected. To get around this problem, I simply moved the variable
that I needed before the statement InitializeComponent();

To me it shows that you have to be careful where you insert your
classes...but that's too general a statement to be of much use, I
admit.

Note that this isn't a matter of where the variable is *declared* -
it's where it's *initialized*. The location of the variable declaration
doesn't make much difference (in 99.9% of cases, anyway - there are
some edge cases which should be avoided) but if you're going to assume
that the variable contains a useful value, you'd better make sure that
value has been set before you try to use 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