Simple example: Lets say you have class FooObject with a string property Bar, and the following property Foo in your Control:
private FooObject _foo;
public string Foo
{
get
{
return _foo.Bar;
}
set
{
_foo.Bar = value;
}
}
If you initialize _foo in CreateChildControls, then this code could throw a null reference error. The problem would occur if you try to set the value of Foo in the Designer:
<YourControl runat="server" id="newControl" Foo="This will cause a null reference" />
Properties set in the Designer will be set at runtime before any calls to CreateChildControls. You could get lucky if some other property gets set before yours and it calls CreateChildControls. Imagine the .net runtime making the following series of call based on the above:
YourControl newControl = new YourControl();
newControl.Foo = "This will cause a null reference";
ParentControl.Controls.Add(newControl);
Anytime you are initializing an object in CreateChildControls, you should wrap it's property accessor with EnsureChildControls. Even if you do the following:
private FooObject _foo = new FooObject();
public string Foo
{
get
{
return _foo.Bar;
}
set
{
_foo.Bar = value;
}
}
If you set _foo to a new value in CreateChildControls(), the new value will have the default Bar value and not the new one. When creating a control, most properties you expose will operate on private variables whose value will be set in CreateChildControls(), so you should always add the EnsureChildControls.