¿Por qué hay una instancia predeterminada de cada formulario en VB.Net pero no en C#?

Resuelto Shekhar_Pro asked hace 14 años • 2 respuestas

Solo tengo curiosidad por saber que existe la propiedad (Nombre), que representa el nombre de la clase Formulario. Esta propiedad se usa dentro del espacio de nombres para identificar de forma única la clase de la que es una instancia el formulario y, en el caso de Visual Basic, se usa para acceder a la instancia predeterminada del formulario.

Ahora, de dónde proviene esta instancia predeterminada, ¿por qué C# no puede tener un método equivalente a este?

También por ejemplo para mostrar un formulario en C# hacemos algo como esto:

// Only method
Form1 frm = new Form1();
frm.Show();

Pero en VB.Net tenemos ambas formas de hacerlo:

' First common method
Form1.Show()

' Second method
Dim frm As New Form1()
frm.Show()
  1. Mi pregunta proviene de este primer método. ¿Qué es esto Form1? ¿Es una instancia Form1o la Form1clase misma? Ahora, como mencioné anteriormente, el nombre del formulario es la instancia predeterminada en VB.Net. Pero también sabemos que Form1es una clase definida, Designerentonces, ¿cómo pueden ser los mismos nombres tanto para la instancia como para el nombre de la clase? Si Form1es una clase, entonces no existe ningún método (Estático\Compartido) llamado Show(). Entonces, ¿de dónde viene este método?

  2. ¿Qué diferencia tienen en el IL generado?

  3. Y finalmente, ¿por qué C# no puede tener un equivalente de esto?

Shekhar_Pro avatar Jan 15 '11 14:01 Shekhar_Pro
Aceptado

Esto se volvió a agregar al lenguaje en la versión de VB.NET que vino con VS2005. Por demanda popular, los programadores de VB6 tuvieron dificultades para ver la diferencia entre un tipo y una referencia a un objeto de ese tipo. Form1 vs frm en su fragmento. Hay una historia de eso, VB no recibió clases hasta VB4, mientras que los formularios se remontan a VB1. Por lo demás, esto es bastante paralizante para la mente del programador, ya que comprender que la diferencia es muy importante para tener la oportunidad de escribir código orientado a objetos eficaz. Una gran parte de la razón por la que C# no tiene esto.

También puede recuperar esto en C#, aunque no será tan limpio porque C# no permite agregar propiedades y métodos al espacio de nombres global como lo hace VB.NET. Puedes agregar un poco de pegamento al código de tu formulario, así:

public partial class Form2 : Form {
    [ThreadStatic] private static Form2 instance;

    public Form2() {
        InitializeComponent();
        instance = this;
    }

    public static Form2 Instance {
        get {
            if (instance == null) {
                instance = new Form2();
                instance.FormClosed += delegate { instance = null; };
            }
            return instance;
        }
    }
}

Ahora puede usar Form2.Instance en su código, tal como podría usar Form2 en VB.NET. El código en la declaración if del captador de propiedades debe trasladarse a su propio método privado para hacerlo eficiente; lo dejé así para mayor claridad.

Por cierto, el atributo [ThreadStatic] en ese fragmento es lo que ha hecho que muchos programadores de VB.NET dejen de usar subprocesos en total desesperación. Un problema cuando la abstracción tiene fugas. Realmente es mejor que no hagas esto en absoluto.

Hans Passant avatar Jan 15 '2011 11:01 Hans Passant

Básicamente, VB está agregando una gran cantidad de código a su proyecto a sus espaldas.

La forma más sencilla de ver lo que está pasando es crear un proyecto mínimo y verlo con Reflector. Acabo de crear una nueva aplicación WinForms con VB y agregué esta clase:

Public Class OtherClass    
    Public Sub Foo()
        Form1.Show()
    End Sub
End Class

El código compilado para Foo se ve así cuando se descompila como C#:

public void Foo()
{
    MyProject.Forms.Form1.Show();
}

MyProject.Formses una propiedad de la MyProjectclase generada, de tipo MyForms. Cuando empiezas a profundizar en esto, ves cantidades bastante grandes de código generado allí.

C# podría hacer todo esto, por supuesto, pero normalmente no tiene un historial de hacer tanto a tus espaldas. Crea métodos y tipos adicionales para cosas como tipos anónimos, bloques iteradores, expresiones lambda, etc., pero no de la misma manera que lo hace VB aquí. Todo el código que crea C# corresponde al código fuente que usted ha escrito, simplemente transformado inteligentemente.

Por supuesto, existen argumentos a favor de ambos enfoques. Personalmente prefiero el enfoque de C#, pero probablemente no sea una sorpresa. No veo por qué debería haber una forma de acceder a una instancia de un formulario como si fuera un singleton, pero solo para formularios... Me gusta que el lenguaje funcione de la misma manera ya sea que esté usando clases GUI o cualquier otra cosa. , básicamente.

Jon Skeet avatar Jan 15 '2011 07:01 Jon Skeet