Calling virtual methods in constructors can create potential problems. See the following sample code
Execution Flow:
public class BaseClassType
{
public BaseClassType()
{
DoCall();
}
public virtual void DoCall()
{
Console.WriteLine("BaseClass DoCall");
}
}
public class DerivedClassType : BaseClassType
{
private string type;
public DerivedClassType()
{
type = "Derived";
}
public override void DoCall()
{
Console.WriteLine("The type is:" + type.ToUpper());
}
}
Create DerivedClassType object in Main()
DerivedClassType derivedObj = new DerivedClassType();Output: NullReferenceException
Execution Flow:
- When an object constructed in C#, the initializers run in order from the most derived class to the base class, and then constuctors run in order from the base class to the most derived class.
- When we create the new instance of DerivedClassType, the default parameterless constructor in BaseClassType is called first. i.e. control goes to DoCall() function
- When BaseClassType calls DoCall(), it is virtual method and looks for overridden method . So, it is directed to the DoCall() in DerivedClassTpe.
- However, at this point the code in DerivedClassType constructor has not yet executed, and so the type variable is still referring null.
- When we call type.ToUpper(), It gives null reference exception . I.e. DoCall() method executing before DerivedClassType constructor execution.
- check VS code analysis rule CA2214
Check another example :
public class BadlyConstructedType
{ protected string initialized = "No";
public BadlyConstructedType()
{ Console.WriteLine("Calling base ctor.");
DoSomething();
}
public virtual void DoSomething()
{ Console.WriteLine ("Base DoSomething");
}
}
public class DerivedType : BadlyConstructedType
{ public DerivedType ()
{ Console.WriteLine("Calling derived ctor.");
initialized = "Yes";
}
public override void DoSomething()
{ Console.WriteLine("Derived DoSomething - initialized ? {0}", initialized);
}
}
DerivedType derivedInstance = new DerivedType();
Output :
Calling base ctor.
Derived DoSomething -
initialized ? No
Calling derived ctor.
Happy Coding :)
No comments:
Post a Comment