作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我今天审查了一些代码并发现了一些代码(这段代码准确地描述了)...
public abstract class FlargBase{
public FlargBase(){
this.DoSomething();
}
public abstract void DoSomething();
}
public class PurpleFlarg: FlargBase{
public PurpleFlarg()
: base(){
}
public override void DoSomething(){
// Do something here;
}
}
编译器没有给出错误或警告,但 CodeAnalysis 警告调用链包含对虚拟方法的调用,可能会产生意外结果。
我很好奇,因为在我看来,可能会发生两种情况。
这段代码已经在生产环境中运行了几个月。它显然工作正常,没有人注意到任何奇怪的行为。
我希望 StackOverflow 的天才们可以让我深入了解这段代码的行为和后果。
最佳答案
在第一个构造函数运行之前,C# 对象已完全构造并初始化为零。基础构造函数将调用虚方法的派生实现。
这样做被认为是不好的风格,因为当尚未调用派生类的构造函数时,派生的实现可能会表现得很奇怪。但行为本身是明确定义的。如果您在要求构造函数中的代码已经运行的派生实现中不执行任何操作,它将起作用。
您可以想象运行时首先调用最派生的构造函数。它的第一个 Action 是隐式调用基本构造函数。我不确定它是否真的是这样实现的,但是由于某些 .net 语言允许您在派生构造函数的任意点调用基类构造函数,我希望 C# 简单地调用基类构造函数作为派生的第一个 Action 构造函数。
这种行为与 C++ 处理它的方式非常不同。在 C++ 中,派生类一个接一个地构造,并且在派生类的构造函数启动之前,对象仍然具有基类的类型,派生类的覆盖将被忽略。
关于c# - 编译器琐事 : What is consequence of this code,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7046414/
我是一名优秀的程序员,十分优秀!