m.e*_*son 6 .net c# virtual exception access-modifiers
我正在测试在构造函数中调用虚拟成员的效果,并发现在调用该成员时,生成的异常被包装在一个TargetInvocationException.
根据文档,这是:
由反射调用的方法抛出的异常
但是我没有意识到通过反射的任何调用.那么这是否意味着虚拟成员总是通过反射来调用?如果没有,为什么在这种情况下呢?
代码:
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!
}
}
Run Code Online (Sandbox Code Playgroud)
不,通过虚拟调度调用虚方法.
这里没有使用反思.并且它也不适用于任何虚拟方法调用.我相信异常的文档有点误导,因为通过反射调用的方法抛出了这种类型的异常,但并非如此.
如果有人对为什么问题中的代码给出异常感到好奇,那是因为构造函数的执行顺序.该ClassB构造是一样的:
public ClassB() : base()
{
_output = "Constructor has occured";
}
Run Code Online (Sandbox Code Playgroud)
注意调用base(),它在构造ClassB函数运行之前调用基本构造函数,因此在分配_output之前调用.该SplitTheWords虚拟方法被称为在基构造,其解析为ClassB.SplitTheWords.此方法尝试使用_output,因此错误.
为了更详细地了解为什么不应该从构造函数调用虚方法,这个SO问题有一些有用的信息.埃里克利珀也对为什么是这样的情况下,一个很好的博客文章在这里.