I was testing the effects of calling a virtual member in a constructor, and discovered that when calling that member the resulting exception was wrapped within a TargetInvocationException
.
According to the docs this is:
The exception that is thrown by methods invoked through reflection
However I'm unaware of any invokations via reflection. So does this mean virtual members are always called via reflection? If not why is it so in this case?
The code:
class ClassA
{
public ClassA()
{
SplitTheWords();
}
public virtual void SplitTheWords()
{
//I've been overidden
}
}
class ClassB : ClassA
{
private readonly String _output;
public ClassB()
{
_output = "Constructor has occured";
}
public override void SplitTheWords()
{
String[] something = _output.Split(new[]{' '}); //TargetInvocationException!
}
}
No, virtual methods are called via virtual dispatch.
Reflection is not being used here. And nor is it for any virtual method calls. I believe the documentation for the exception is slightly misleading in that exceptions of this type are thrown by methods invoked via reflection, however not exclusively so.
If anyone is curious as to why the code in the question gives an exception, it is because of the order in which the constructors are executed. The ClassB
constructor is the same as:
public ClassB() : base()
{
_output = "Constructor has occured";
}
Note the call to base()
, this calls the base constructor before the ClassB
constructor is run and, hence, before _output is assigned. The SplitTheWords
virtual method is called in the base constructor, which resolves to ClassB.SplitTheWords
. This method attempts to use _output
, hence the error.
For a more detailed look at why virtual methods should not be called from constructors this SO question has some useful information. Eric Lippert also has a very good blog post on why this is the case here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With