values recorrer ejemplos diccionario c# vb.net compiler-construction initialization

recorrer - map dictionary c#



Escribí un programa que permite que dos clases "peleen". Por la razón que sea C#siempre gana. ¿Qué pasa con VB.NET? (4)

El problema aquí es que VB está llamando al constructor base antes de establecer su valor de campo. Entonces la clase de Jugador base almacena cero.

.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

Escribí un programa que permite que dos clases "peleen". Por la razón que sea C # siempre gana. ¿Qué pasa con 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"); }

Aquí están los jugadores: Jugador A en C #:

public class A : Player { private int desiredPower = 100; public override int GetPower { get { return desiredPower; } } }

Jugador B en VB.NET:

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

Y aquí hay una clase base.

public abstract class Player { public int Power { get; private set; } public abstract int GetPower { get; } protected Player() { Power = GetPower; } }


Esto sucede porque C # primero inicializa los campos de clase, y los constructores de base de llamadas. En cambio, VB hace lo contrario, de modo que cuando en VB asigna su valor a Energía, el campo privado aún no se ha inicializado y su valor es 0.


Para cuando el constructor en B complete, ambos jugadores tendrán un valor teórico de 100 en sus miembros privados.

Sin embargo, debido a las características internas superiores de C #, la CLI generalmente considera que los valores enteros y otros valores primitivos compilados a partir de ese idioma son más altos, y los valores de VB.NET son más bajos, incluso cuando contienen los mismos bits.


Promoviendo mis comentarios a una respuesta:

Yo:

Intenta escribir cada "poder" en la consola también

Bromista:

C #: 100 VB.NET: 0

Yo:

Como sospechaba. Parece que VB.Net está llamando al constructor Base antes que el constructor heredado, y por lo tanto la variablePower desired de VB sigue siendo 0, mientras que C # lo hace a la inversa (recuerde, la inicialización literal ocurre al final del constructor).

Actualizar:
Quería encontrar algo de documentation sobre el comportamiento (de lo contrario, estás viendo un comportamiento que podría cambiar por debajo de ti con cualquier versión nueva de .Net). Desde el enlace:

El constructor de la clase derivada llama implícitamente al constructor para la clase base

y

Los objetos de la clase base siempre se construyen antes de cualquier clase derivada. Por lo tanto, el constructor para la clase base se ejecuta antes que el constructor de la clase derivada.

Esos están en la misma página y parecen ser mutuamente excluyentes, pero supongo que el constructor de la clase derivada se invoca primero, pero se supone que invocará al constructor base antes de realizar cualquier otro trabajo. Por lo tanto, no es el orden del constructor lo importante, sino la manera en que se inicializan los literales.

También encontré esta referencia , que dice claramente que el orden se deriva de los campos de instancia, luego del constructor base y del constructor derivado.