猿问
构造函数中的虚拟成员调用
构造函数中的虚拟成员调用
我收到ReSharper关于从对象构造函数调用虚拟成员的警告。
为什么不做这件事呢?
撒科打诨
浏览 485
回答 3
3回答
一只斗牛犬
在构造用C#编写的对象时,所发生的情况是初始化器按顺序从派生最多的类运行到基类,然后构造函数按顺序从基类运行到派生最多的类(请参阅Eric Lippert的博客,了解为什么这是).在.NET对象中,也不会在构造时更改类型,而是从派生最多的类型开始,方法表是派生最多的类型。这意味着虚拟方法调用总是在派生最多的类型上运行。当您将这两个事实结合在一起时,就会遇到这样的问题:如果在构造函数中进行虚拟方法调用,并且它的继承层次结构中的派生类型不是最多的,那么它将被调用到其构造函数尚未运行的类上,因此可能处于不适合调用该方法的状态。当然,如果您将类标记为密封的,以确保它是继承层次结构中派生最多的类型,那么这个问题就会得到缓解-在这种情况下,调用虚拟方法是完全安全的。
0
0
0
梦里花落0921
C#的规则与Java和C+的规则有很大的不同。当您在C#中的某个对象的构造函数中时,该对象以完全初始化(只是不是“构造”)形式存在,作为它的完全派生类型。namespace Demo{ class A { public A() { System.Console.WriteLine("This is a {0},", this.GetType()); } } class B : A { } // . . . B b = new B(); // Output: "This is a Demo.B"}这意味着,如果从A的构造函数调用虚拟函数,它将解析为B中的任何覆盖(如果提供了重写)。即使你故意像这样设置A和B,完全理解系统的行为,你以后也会感到震惊。假设您在B的构造函数中调用虚拟函数,“知道”它们将酌情由B或A处理。然后时间流逝,其他人决定他们需要定义C,并覆盖那里的一些虚拟函数。突然之间,B的构造函数以调用C中的代码结束,这可能会导致相当令人惊讶的行为。无论如何,避免构造函数中的虚拟函数可能是个好主意,因为规则是C#、C+和Java之间有很大的不同。您的程序员可能不知道该期待什么!
0
0
0
随时随地看视频
慕课网APP
相关分类
C#
typedef入门问题
1 回答
我要回答