我写了一个程序,允许两个类"战斗".无论出于何种原因,C#总能获胜.VB.NET有什么问题?
static void Main(string[] args) { Player a = new A(); Player b = new B(); if (a.Power > b.Power) Console.WriteLine("C# won"); else if (a.Power < b.Power) Console.WriteLine("VB won"); else Console.WriteLine("Tie"); }
以下是玩家:C#中的玩家A:
public class A : Player { private int desiredPower = 100; public override int GetPower { get { return desiredPower; } } }
VB.NET中的玩家B:
Public Class B Inherits Player Dim desiredPower As Integer = 100 Public Overrides ReadOnly Property GetPower() As Integer Get Return desiredPower End Get End Property End Class
这是一个基类.
public abstract class Player { public int Power { get; private set; } public abstract int GetPower { get; } protected Player() { Power = GetPower; } }
Jb Evain.. 45
这里的问题是VB在设置其字段值之前调用基础构造函数.所以基础Player类存储零.
.method public specialname rtspecialname instance void .ctor() cil managed { // Code size 15 (0xf) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void [base]Player::.ctor() IL_0006: ldarg.0 IL_0007: ldc.i4.s 100 IL_0009: stfld int32 B::desiredPower IL_000e: ret } // end of method B::.ctor
Joel Coehoor.. 16
将我的评论推荐给答案:
我:
尝试将每个"电源"写入控制台
恶作剧:
C#:100 VB.NET:0
我:
我怀疑.看起来VB.Net在继承的构造函数之前调用Base构造函数,因此VB的desiredPower变量仍为0,而C#反向执行(记住,文本初始化发生在构造函数的末尾).
更新:
我想找到一些关于行为的文档(否则你会看到任何新的.Net版本可能会改变你的行为).从链接:
派生类的构造函数隐式调用基类的构造函数
和
始终在任何派生类之前构造基类对象.因此,基类的构造函数在派生类的构造函数之前执行.
它们位于同一页面上并且似乎是互斥的,但我认为它首先调用派生类构造函数,但假设它自己在执行任何其他工作之前调用基本构造函数.因此,重要的不是构造函数顺序,而是文本初始化的方式.
我也找到了这个引用,它清楚地表明顺序是派生实例字段,然后是基础构造函数,然后是派生构造函数.
这里的问题是VB在设置其字段值之前调用基础构造函数.所以基础Player类存储零.
.method public specialname rtspecialname instance void .ctor() cil managed { // Code size 15 (0xf) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void [base]Player::.ctor() IL_0006: ldarg.0 IL_0007: ldc.i4.s 100 IL_0009: stfld int32 B::desiredPower IL_000e: ret } // end of method B::.ctor
将我的评论推荐给答案:
我:
尝试将每个"电源"写入控制台
恶作剧:
C#:100 VB.NET:0
我:
我怀疑.看起来VB.Net在继承的构造函数之前调用Base构造函数,因此VB的desiredPower变量仍为0,而C#反向执行(记住,文本初始化发生在构造函数的末尾).
更新:
我想找到一些关于行为的文档(否则你会看到任何新的.Net版本可能会改变你的行为).从链接:
派生类的构造函数隐式调用基类的构造函数
和
始终在任何派生类之前构造基类对象.因此,基类的构造函数在派生类的构造函数之前执行.
它们位于同一页面上并且似乎是互斥的,但我认为它首先调用派生类构造函数,但假设它自己在执行任何其他工作之前调用基本构造函数.因此,重要的不是构造函数顺序,而是文本初始化的方式.
我也找到了这个引用,它清楚地表明顺序是派生实例字段,然后是基础构造函数,然后是派生构造函数.