62

我写了一个程序,允许两个班级“战斗”。无论出于何种原因,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;
    }
}
4

4 回答 4

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
于 2009-04-02T21:11:01.480 回答
16

将我的评论推广到答案:

我:

尝试将每个“电源”写入控制台

恶作剧者:

C#:100 VB.NET:0

我:

正如我所怀疑的那样。看起来 VB.Net 在继承构造函数之前调用 Base 构造函数,因此 VB 的 desiredPower 变量仍然为 0,而 C# 则相反(请记住,文字初始化发生在构造函数的末尾)。

更新:
我想找到一些有关该行为的文档(否则,您正在查看的行为可能会随着任何新的 .Net 版本而改变)。从链接:

派生类的构造函数隐式调用基类的构造函数

基类对象总是在任何派生类之前构造。因此,基类的构造函数在派生类的构造函数之前执行。

它们在同一页面上并且似乎是互斥的,但我认为它的意思是首先调用派生类构造函数,但假设它本身在执行任何其他工作之前调用基本构造函数。因此,重要的不是构造函数顺序,而是初始化文字的方式。

我还找到了这个参考,它清楚地表明顺序是派生实例字段,然后是基本构造函数,然后是派生构造函数。

于 2009-04-02T21:10:25.443 回答
1

到 B 上的构造函数完成时,两个玩家的私有成员的理论值都将是 100。

然而,由于 C# 的优越内部结构,CLI 通常认为从该语言编译的整数和其他原始值值较高,而从 VB.NET 编译的值较低,即使它们包含相同的位也是如此。

于 2009-04-02T21:05:22.023 回答
1

发生这种情况是因为 C# 首先初始化类字段,然后调用基构造函数。相反,VB 则相反,因此在 VB 中将值分配给 Power 时,私有字段尚未初始化,其值为 0。

于 2010-08-04T14:50:44.603 回答