为什么C#在基础构造函数之前设置私有变量,而VB.NET则反其道而行之?

有一个问题比较C#代码和VB.NET,看似相同的代码之间的结果是完全不同的。 ( 我编写了一个程序,允许两个类“战斗”。无论出于何种原因,C#总能获胜.BB.NET有什么问题? )

给出的解释是C#将初始化类字段,然后调用基础构造函数,但VB.NET完全相反。

我的问题是 – 为什么?

这些语言有不同的技术原因吗? 乍一看,似乎任何一种方法都同样有效,但我无法理解为什么他们不会选择相同的方法。

编辑:正如’Jeffrey L Whitledge’指出的那样,VB6没有inheritance,所以我认为我们不能说“保持VB.NET和VB6更紧密相关”。

在派生类构造函数运行之前,基础构造函数可以将对象公开给外部世界。 虽然人们应该经常避免这样做,但有时候这是必要的。 例如,一个可能有两个对象保持彼此的引用,并且每个对象可能具有类不变量,以至于对另一个对象的引用必须是有效的。 创建这样一对对象需要让一个对象的构造函数将部分构造的对象传递给另一个对象,或者在满足类不变量之前让对象的构造函数返回。

如果在运行基类构造函数之后才运行derived-class字段初始值设定项,并且如果基类构造函数将对象公开给外部世界,那么这意味着该对象在任何派生之前将暴露给外部世界 – 类初始化已经发生。 C#的创建者不喜欢这个想法,因此他们使派生类初始化程序在基类构造函数之前运行。

另一方面,在基类构造函数之前运行派生类初始化程序有一个缺点:这些初始值设定项不能对正在构造的对象进行任何引用。 他们也无法使用传递给构造函数的任何参数。 在将控制权移交给基类构造函数之前将对象部分初始化可能会很好,但是对于如何初始化它有一些严格的限制; 在运行基础构造函数之前,可能会也可能无法使对象处于完全有用的状态。

vb.net的创建者显然认为,因为在基础构造函数之前运行初始化程序并不能消除处理暴露给外部世界的部分构造对象的需要,并且因为它排除了使用某些有用的技术,所以它更好让初始化程序在基础构造函数之后运行。 这使得基础构造函数可以将其中一个参数作为字段公开,然后让派生类在derived-class字段初始值设定项中使用该字段的值。

可以说,C#方法允许人们做vb.net没有的事情,但反之则不然(可以通过简单地写入构造函数开头的字段来实现vb样式的字段初始化器)。 另一方面,将字段的声明和初始化彼此相邻比在一个地方具有声明和在其他地方初始化更清晰。 太糟糕了,两种语言都不允许人们指定某些特定的字段声明应遵循与规范相反的范例。