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

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 manera única la clase de la que el Formulario es una instancia y, en el caso de Visual Basic, se utiliza para acceder a la instancia predeterminada del formulario.

Ahora, de donde viene esta Instancia predeterminada, ¿por qué C no puede tener un método equivalente a esto?

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 dos 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 este Form1 , es una instancia de Form1 o la clase Form1 sí? Ahora, como mencioné anteriormente, el nombre del formulario es la instancia predeterminada en VB.Net. Pero también sabemos que Form1 es una clase definida en Designer entonces, ¿cómo pueden los nombres ser iguales tanto para la instancia como para el nombre de clase? Si Form1 es una clase, entonces no hay un método (Estático / Compartido) llamado Show (). Entonces, ¿de dónde viene este método?

  2. ¿Qué diferencia tienen en la IL generada?

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

Esto se agregó al lenguaje en la versión de VB.NET que vino con VS2005. Por demanda popular, los progtwigdores de VB6 tuvieron dificultades para ver la diferencia entre un tipo y una referencia a un objeto de ese tipo. Form1 contra frm en su fragmento. Hay historia para eso, VB no recibió clases hasta VB4, mientras que las formas regresan a VB1. Esto de otro modo es paralizante para la mente del progtwigdor, entendiendo que la diferencia es muy importante para tener la oportunidad de escribir un código eficaz orientado a objetos. Una gran parte de la razón por la que C # no tiene esto.

También puede obtener 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. Puede agregar un poco de pegamento a su código de formulario, como este:

 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, al igual que podría usar Form2 en VB.NET. El código en la statement if del getter de propiedad debe moverse a su propio método privado para hacerlo eficiente, lo dejé así para mayor claridad.

Dicho sea de paso, el atributo [ThreadStatic] en ese fragmento es lo que ha hecho que muchos progtwigdores de VB.NET abandonen el enhebrado en total desesperación. Un problema cuando la abstracción tiene fugas. Realmente es mejor que no hagas esto en absoluto.

VB está agregando una carga de código en tu proyecto a tus espaldas, básicamente.

La forma más fácil de ver qué sucede 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 comstackdo para Foo se ve así cuando se descomstack como C #:

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

MyProject.Forms es una propiedad en la clase MyProject generada, de tipo MyForms . Cuando comienzas a sumergirte en esto, ves grandes cantidades de código generado allí.

C # podría hacer todo esto, por supuesto, pero normalmente no tiene un historial de hacer tanto a sus espaldas. Construye métodos y tipos adicionales para cosas como tipos anónimos, bloques de iteradores, expresiones lambda, etc., pero no de la misma manera que VB lo hace aquí. Todo el código que las comstackciones de C # corresponden al código fuente que has escrito, se transforma de forma inteligente.

Hay argumentos para ambos enfoques, por supuesto. Personalmente prefiero el enfoque C #, pero eso 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 de GUI o cualquier otra cosa , básicamente.