2011-01-15 19 views
40

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.¿Por qué hay una instancia predeterminada de cada formulario en VB.Net pero no en C#?

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 una forma en C# que hacer algo como esto:

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

Pero en VB.Net tenemos dos maneras de hacerlo:

' First common method 
Form1.Show() 

' Second method 
Dim frm As New Form1() 
frm.Show() 
  1. Mi la pregunta proviene de este primer método. ¿Qué es esto Form1, es una instancia de Form1 o la clase Form1? 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 Mostrar(). 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?

+2

"Qué diferencia tienen en la IL generada": descargue y use .NET Reflector para descubrirlo usted mismo. Es tremendamente útil y gratis. –

+2

No me gustaría esta "característica" en C# ... Es solo un truco para ocultar el hecho de que necesita crear una instancia de una clase para usarla. ¡Es realmente una idea terrible! Además, está muy poco documentado y tiene efectos secundarios inesperados y peligrosos (p. Ej., Cada tema tiene su propia "instancia predeterminada" del formulario te) –

+0

@ThomasLevesque no quiero esa función ... solo quería saber cómo se hace y es posible ... :) –

Respuesta

31

Esto se ha agregado de nuevo al idioma en la versión de VB.NET incluida 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 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 programador, entendiendo que la diferencia es muy importante para tener la oportunidad de escribir 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. Se puede añadir un poco de pegamento en el código del 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 utilizar Form2.Instance en su código, al igual que lo podría utilizar Form2 en VB.NET. El código en la declaración 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 programadores de VB.NET abandonen el enhebrado con total desesperación. Un problema cuando la abstracción tiene fugas. Usted es realmente mejor no haciendo esto en absoluto.

+0

seguro que no lo haré;) .. Muchas gracias por su * pegamento * me dio una mejor comprensión de lo que lo hizo posible. –

+3

Una razón importante por la que se agregó a VB.Net fue ayudar a portar el código existente de VB1-3 a VB.Net, donde la característica se habrá utilizado porque no había otra alternativa. Es por eso que me complace que se haya agregado: personalmente, no creo que deba usarse en un código nuevo. Además, a pesar de mi apoyo para esta función y algo de experiencia con VB6, no creo que personalmente tenga ningún problema para entender la diferencia entre un tipo y una referencia a una instancia del tipo :) – MarkJ

+2

Así que básicamente se modificó el lenguaje VB.NET porque los usuarios eran demasiado estúpidos para entender OOP ... Siempre me sorprende la forma en que este lenguaje puede ser defectuoso de muchas maneras, sin dejar de tener casi las mismas características que C#. –

23

VB está agregando una carga de código en su proyecto detrás de su espalda, básicamente.

La manera más fácil de ver qué ocurre es crear un proyecto mínimo y verlo con Reflector. Acabo de crear una nueva aplicación WinForms con VB y añadió esta clase:

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

El código compilado para Foo tiene este aspecto cuando descompilada como C#:

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

MyProject.Forms es una propiedad en el generada MyProject clase, 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 compilaciones de C# corresponden al código fuente que has escrito, se transforma de forma inteligente.

Existen 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 el idioma para que funcione de la misma manera si uso GUI clases o cualquier otra cosa, básicamente.

+0

Form1.Show() está generando el error ''WindowsApplication2.Form1' no puede referirse a sí mismo a través de su instancia predeterminada; use 'Me' en su lugar. ' –

+3

@Javed: Entonces, presumiblemente, no lo está utilizando de una clase diferente, como lo estoy en mi ejemplo. –

Cuestiones relacionadas