gpt4 book ai didi

c# - 编译器琐事 : What is consequence of this code

转载 作者:太空狗 更新时间:2023-10-30 00:02:01 25 4
gpt4 key购买 nike

我今天审查了一些代码并发现了一些代码(这段代码准确地描述了)...

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 警告调用链包含对虚拟方法的调用,可能会产生意外结果。

我很好奇,因为在我看来,可能会发生两种情况。

  1. 创建基类的实例将调用未定义实现的方法。我希望编译器出错,或者运行时由于缺少实现而抛出异常。我假设编译器正在提供 {} 的实现我输入了错误的原始代码;它确实包含类的抽象关键字。
  2. 创建派生类的实例将导致调用尚未实际构建的类的方法。我原以为这会引发异常。

这段代码已经在生产环境中运行了几个月。它显然工作正常,没有人注意到任何奇怪的行为。

我希望 StackOverflow 的天才们可以让我深入了解这段代码的行为和后果。

最佳答案

在第一个构造函数运行之前,C# 对象已完全构造并初始化为零。基础构造函数将调用虚方法的派生实现。

这样做被认为是不好的风格,因为当尚未调用派生类的构造函数时,派生的实现可能会表现得很奇怪。但行为本身是明确定义的。如果您在要求构造函数中的代码已经运行的派生实现中不执行任何操作,它将起作用。

您可以想象运行时首先调用最派生的构造函数。它的第一个 Action 是隐式调用基本构造函数。我不确定它是否真的是这样实现的,但是由于某些 .net 语言允许您在派生构造函数的任意点调用基类构造函数,我希望 C# 简单地调用基类构造函数作为派生的第一个 Action 构造函数。


这种行为与 C++ 处理它的方式非常不同。在 C++ 中,派生类一个接一个地构造,并且在派生类的构造函数启动之前,对象仍然具有基类的类型,派生类的覆盖将被忽略。

关于c# - 编译器琐事 : What is consequence of this code,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7046414/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com