2009-01-12 50 views
17

Obtuve un módulo de utilidad ya que VB.NET no tiene clase estática como C# y el módulo es la clase estática en VB.NET. La razón por la que uso el módulo es porque estoy usando el método de extensión y solo se puede usar en el módulo.VB.NET: ¿Cómo hacer referencia al módulo VB.NET?

No puedo hacer referencia a este módulo pero si coloco mi código en una clase. Puedo hacer referencia a esto sin ningún problema. ¿Cuál podría ser la razón? Me perdí C#.

Editar: El módulo está dentro de una utilidad de llamada de biblioteca de clase.

+0

Creo que malinterpreta las capacidades de VB.Net. Los módulos no son clases compartidas/estáticas, son globales para los métodos del espacio de nombres que se pueden usar en cualquier lugar. Por lo general, son de tipo abstracto, no extensiones. Funciones, Subs e incluso Extensiones todas viven fuera de la burbuja OOP, descrita por @ Konrad-Rudolph – GoldBishop

+0

Otro punto, para futuros espectadores ... Los nombres de los Módulos no deben tener el mismo nombre entre las Bibliotecas. Los nombres deben ser únicos en el nombre entre los usos. – GoldBishop

Respuesta

9

No puedo hacer referencia a este módulo pero si coloco mi código en una clase. Puedo hacer referencia a esto sin ningún problema. ¿Alguien sabe por qué?

Porque los módulos en VB no son clases y no se pueden usar para instanciar objetos. Más bien, son algo similar a los espacios de nombres, con la diferencia de que los espacios de nombres no pueden contener funciones directamente. Entonces, la razón de los módulos es proporcionar una forma de agrupar funciones lógicamente que no pertenecen a una clase.

Esto tiene mucho sentido si tenemos en cuenta que no todo pertenece lógicamente a una clase. Considere System.Math. No hay absolutamente ninguna razón para hacer de eso una clase, aparte de un extraño purp de OOP.

Por cierto, tampoco puede hacer referencia a clases estáticas en C#, al menos no si entiendo correctamente lo que quiere decir con "referencia". Quizás puedas aclarar esto.

+0

Siempre pensé eso, pero ¿qué hay de malo en colocarlo en una clase "Compartida"? Si una Función toma datos, hace un cálculo y arroja resultados, sin usar o modificar nada más aparte de los datos de entrada, ¿por qué no puede estar en una clase y marcado como "Compartido"? – SqlRyan

+1

La pregunta es: ¿por qué debería? ¿Qué ventaja tiene la clase? OOP como paradigma solo es útil si tiene una ventaja. Las clases sin datos (y sin lugar como un tipo de marcador) no sirven para ningún propósito. –

+0

@SqlRyan ¿por qué un genérico debe residir con la burbuja de una clase? ¿Por qué no residir en el espacio de nombres? o mejor aún, solo en la Biblioteca misma. Si no tiene relevancia para la clase o el espacio de nombres, ¿por qué debería estar vinculado a uno? Los módulos son una forma de Biblioteca de crear métodos sin casarlos estrictamente con un Objeto que no describe adecuadamente su uso. – GoldBishop

1

¿Quizás los métodos/subs no son públicos? Tuve ese problema una vez, y me permitió acceder al código local en tu clase, pero no si estaba fuera de tu clase y marcado como "Privado".

0

No entiendo lo que está preguntando.

VB.NET hace tienen clases estáticas, al igual que en C#, VB.NET porque en un ModuleES un static class. Ellos son uno y lo mismo. Cualquier cosa que pueda hacer con una clase estática que puede hacer con un Módulo. ¿Quizás no ha marcado correctamente su acceso público/privado/protegido?

+4

@Joel: no, no son lo mismo en un nivel de idioma. En particular, los módulos implícitamente importan sus nombres en el espacio de nombres actual. Esto significa que no es necesario que el prefijo de los nombres de un módulo con el nombre del módulo se refiera a ellos (siempre que se importe el espacio de nombres circundante del módulo). –

+0

@Joel: Su información no es correcta .... 'Module' __IS NOT__ a' static class' – GoldBishop

0
Imports System.Web 
Imports System.Web.UI 

Module ResponseHelper 

    <System.Runtime.CompilerServices.Extension()> _ 
    Public Sub Redirect(ByVal response As Net.HttpWebResponse, _ 
         ByVal url As String, ByVal target As String, _ 
         ByVal windowFeatures As String) 

     If String.IsNullOrEmpty(target) Or _ 
      target.Equals("_self", StringComparison.OrdinalIgnoreCase) And _ 
      String.IsNullOrEmpty(windowFeatures) Then 
      response.Redirect(url, target, windowFeatures) 
     Else 
      Dim page As Page = CType(HttpContext.Current.Handler, Page) 
      If page Is Nothing Then 
       Throw New InvalidOperationException("Cannot redirect to new window outside Page context.") 
      End If 
      url = page.ResolveClientUrl(url) 
      Dim script As String 
      If String.IsNullOrEmpty(windowFeatures) Then 
       script = "window.open(""{0}"", ""{1}"", ""{2}"";" 
      Else 
       script = "window.open(""{0}"", ""{1}"");" 
      End If 
      script = String.Format(script, url, target, windowFeatures) 
      ScriptManager.RegisterStartupScript(page, GetType(Page), "Redirect", script, True) 

     End If 
    End Sub 

End Module 
+0

¿Está intentando sobrescribir response.redirect con una función javascript?. < – Shawn

42

Debe marcar el módulo como Módulo público.

6

.Los compiladores pueden tomar cualquier tipo de sintaxis de lenguaje y convertirlo en un equivalente .NET. A veces hay una correspondencia uno a uno otras veces no es así.

Al usar .NET Reflector puede ver lo que el compilador realmente está haciendo.

En VB.NET existe el módulo debido a la herencia heredada de Visual BASIC y en parte de Microsoft BASIC.

El VB.compilador NET tomar este

Public Module CoreModule 
    Dim R As New System.Random(CInt(Microsoft.VisualBasic.Timer)) 
    Public Function D(ByVal Roll As Integer) As Integer 
     Return R.Next(0, Roll) + 1 
    End Function 

    Public Function _1D6() As Integer 
     Return D(6) 
    End Function 

    Public Function _2D6() As Integer 
     Return D(6) + D(6) 
    End Function 

    Public Function _3D6() As Integer 
     Return D(6) + D(6) + D(6) 
    End Function 

    Public Function _4D6() As Integer 
     Return D(6) + D(6) + D(6) + D(6) 
    End Function 

    Public Function CRLF() As String 
     Return Microsoft.VisualBasic.ControlChars.CrLf 
    End Function 
End Module 

y convertirlo en esto (código dejado de lado por razones de brevedad)

Public NotInheritable Class CoreModule 
    ' Methods 
    Shared Sub New() 
    Public Shared Function _1D6() As Integer 
    Public Shared Function _2D6() As Integer 
    Public Shared Function _3D6() As Integer 
    Public Shared Function _4D6() As Integer 
    Public Shared Function CRLF() As String 
    Public Shared Function D(ByVal Roll As Integer) As Integer 

    ' Fields 
    Private Shared R As Random 
End Class 

En C# es el equivalente de este

public sealed class CoreModule 
{ 
    // Fields 
    private static Random R; 

    // Methods 
    static CoreModule(); 
    public static int _1D6(); 
    public static int _2D6(); 
    public static int _3D6(); 
    public static int _4D6(); 
    public static string CRLF(); 
    public static int D(int Roll); 
} 

Todo lo que importa es que el emitido CIL hace el trabajo correctamente.

Esta capacidad es la razón principal por la que tantos programadores antiguos de Visual Basic 6 están muy molestos por los cambios de MS en el lenguaje. Por ejemplo, la palabra clave Integer emite un Int32 en lugar de un Int16.

Los módulos están expuestos a otros ensambles que hacen referencia al ensamblaje original, siempre que el módulo se declare público.

+0

Aclaración, BasicA nunca fue propiedad de Microsoft. ..Microsoft comenzó a ser dueño de QBasic. [Básico] (https://en.wikipedia.org/wiki/BASIC) – GoldBishop