【发布时间】:2011-01-05 09:25:24
【问题描述】:
在调试 VB.NET 中涉及初始化实例变量的顺序的一个特别棘手的问题后,我发现我对 C# 的预期行为与 VB.NET 中的实际行为之间存在重大差异。
注意事项: 这个问题涉及到 VB.NET 和 C# 的行为略有不同。如果你是一个语言偏执者,除了“这就是你应该使用 C#,菜鸟” 之外无法提供答案,那么这里没有任何内容可供你查看;请继续前进。
具体来说,我预计 C# Language Specification 概述的行为(已添加重点):
当实例构造函数没有构造函数初始值设定项,或者它具有
base(...)形式的构造函数初始值设定项时,该构造函数隐式执行由在其类中声明的实例字段的变量初始值设定项指定的初始化。 这对应于在进入构造函数并在直接基类构造函数的隐式调用之前立即执行的一系列赋值。变量初始值设定项按照它们出现在类声明。
将其与 VB.NET 语言规范中关于Instance Constructors 的部分进行对比,其中说(添加了重点):
当构造函数的第一条语句为
MyBase.New(...)形式时,构造函数隐式执行由类型中声明的实例变量的变量初始化器指定的初始化。 这对应于在调用直接基类型构造函数后立即执行的一系列赋值。 这样的排序确保所有基实例变量在任何有权访问该实例的语句之前由其变量初始化器初始化执行。
这里的差异是显而易见的。 C# 在调用基本构造函数之前 初始化类级变量。 VB.NET 正好相反,显然更喜欢在设置实例字段的值之前调用基本构造函数。
如果您想查看一些代码,this related question 提供了一个更具体的发散行为示例。不幸的是,它没有提供任何关于如何强制 VB.NET 遵循 C# 建立的模型的提示。
我对这两种语言的设计者为什么选择如此不同的方法感兴趣,而不是对问题的可能解决方法感兴趣。最终,我的问题如下:有什么方法可以在 VB.NET 中编写或构造我的代码,以强制实例变量在 在调用基类型的构造函数之前进行初始化 strong>,就像 C# 中的标准行为一样?
【问题讨论】:
-
我不相信有可能改变这一点 - VB 编译器将反对任何这样做的尝试。如果您依赖这种行为,通常表明代码中的其他地方存在问题。长期以来一直有反对在构造函数中调用虚拟成员的建议(如另一个问题中的示例代码)
-
@Damien:你说得对,在构造函数中调用虚拟成员是不好的做法。不幸的是,这个决定不是我做的。我继承了框架提供的一种类型,同时还覆盖了它的一个虚拟方法。我很确定问题出在我的代码之外,而我唯一能想到的解决这个问题的方法就是对我来说是“丑陋的黑客”。
标签: .net vb.net constructor initialization c#-to-vb.net