I just spent hours being confused by an NullReferenceException
where I thought there shouldn't be one. I was constructing a class like so:
public class MyClass : MyBase<Foo>
{
public MyClass()
{
base.Method(Foo.StaticField);
}
}
where
public class MyBase<T>
{
private SomeObject bar = new SomeObject();
public void Method(object o)
{
this.bar.AnotherMethod(o); // exception thrown here
}
}
Basically my IL was the following:
ctorIl.Emit(OpCodes.Ldarg_0);
ctorIl.Emit(OpCodes.Ldsfld, staticField);
ctorIl.Emit(OpCodes.Box, typeof(FieldType));
ctorIl.Emit(OpCodes.Call, parentMethod);
ctorIl.Emit(OpCodes.Ret);
and I finally figured that it must be that bar
was not being instantiated. I constructed my class in C# and compiled it and found the only difference was that the following should be above the IL above:
ctorIl.Emit(OpCodes.Ldarg_0);
ctorIl.Emit(OpCodes.Call, parentCtor);
// as above
With these lines, my code now works as expected.
So my questions are:
- Why do we need to explicitly call the base constructor to instantiate fields?
- Is there a legitimate use of not calling the base constructor?
- ...and if not, why does the CLR accept it as a valid program?