Program Club

나는 두 개의 클래스가 "싸울"수있는 프로그램을 작성했습니다.

proclub 2020. 11. 28. 12:47
반응형

나는 두 개의 클래스가 "싸울"수있는 프로그램을 작성했습니다. 어떤 이유로 든 C #이 항상 승리합니다. VB.NET의 문제점은 무엇입니까?


나는 두 클래스가 "싸울"수 있도록하는 프로그램을 작성했습니다. 어떤 이유로 든 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;
    }
}

여기서 문제는 VB가 필드 값을 설정하기 전에 기본 생성자를 호출한다는 것입니다. 따라서 기본 Player 클래스는 0을 저장합니다.

.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 #은 반대로 수행합니다 (리터럴 초기화는 생성자의 끝에서 발생 함).

Update:
I wanted to find some documentation on the behavior (otherwise you're looking at behavior that might change out from under you with any new .Net release). From the link:

The constructor of the derived class implicitly calls the constructor for the base class

and

Base class objects are always constructed before any deriving class. Thus the constructor for the base class is executed before the constructor of the derived class.

Those are on the same page and would seem to be mutually exclusive, but I take it to mean the derived class constructor is invoked first, but it is assumed to itself invoke the base constructor before doing any other work. Therefore it's not constructor order that important, but the manner in which literals are initialized.

I also found this reference, which clearly says that the order is derived instance fields, then base constructor, then derived constructor.


By the time the constructor on B completes, both players will have a theoretical value of 100 in their private members.

However because of the superior internals of C#, the CLI generally considers integers and other primitive values values compiled from that language to be higher, and those from VB.NET to be lower, even when they contain the same bits.


This happens because C# first initialize class fields, and than call base constructors. VB instead does the opposite, so when in VB you assign your value to Power, private field is not yet initialized and its value is 0.

참고URL : https://stackoverflow.com/questions/711586/i-wrote-a-program-that-allow-two-classes-to-fight-for-whatever-reason-c-sharp

반응형