Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Un programa de Visual Basic consta de uno o varios archivos de código fuente. Cuando se compila un programa, todos los archivos de origen se procesan juntos; por lo tanto, los archivos de origen pueden depender entre sí, posiblemente de forma circular, sin necesidad de declaración de reenvío. El orden textual de las declaraciones en el texto del programa no suele ser significativo.
Un archivo de origen consta de un conjunto opcional de instrucciones de opción, instrucciones import y atributos, seguidos de un cuerpo de espacio de nombres. Los atributos, que deben tener el Assembly modificador o Module , se aplican al ensamblado o módulo de .NET generado por la compilación. El cuerpo del archivo de origen funciona como una declaración de espacio de nombres implícita para el espacio de nombres global, lo que significa que todas las declaraciones en el nivel superior de un archivo de origen se colocan en el espacio de nombres global. Por ejemplo:
FileA.vb:
Class A
End Class
FileB.vb:
Class B
End Class
Los dos archivos de origen contribuyen al espacio de nombres global, en este caso declarando dos clases con los nombres A completos y B. Dado que los dos archivos de origen contribuyen al mismo espacio de declaración, habría sido un error si cada uno contenía una declaración de un miembro con el mismo nombre.
Nota. El entorno de compilación puede invalidar las declaraciones de espacio de nombres en las que se coloca implícitamente un archivo de origen.
Excepto donde se indique, las instrucciones dentro de un programa de Visual Basic pueden terminarse por un terminador de línea o por dos puntos.
Start
: OptionStatement* ImportsStatement* AttributesStatement* NamespaceMemberDeclaration*
;
StatementTerminator
: LineTerminator
| ':'
;
AttributesStatement
: Attributes StatementTerminator
;
Inicio y finalización del programa
El inicio del programa se produce cuando el entorno de ejecución ejecuta un método designado, que se conoce como punto de entrada del programa. Este método de punto de entrada, que siempre debe denominarse Main, debe compartirse, no se puede incluir en un tipo genérico, no puede tener el modificador asincrónico y debe tener una de las siguientes firmas:
Sub Main()
Sub Main(args() As String)
Function Main() As Integer
Function Main(args() As String) As Integer
La accesibilidad del método de punto de entrada es irrelevante. Si un programa contiene más de un punto de entrada adecuado, el entorno de compilación debe designar uno como punto de entrada. De lo contrario, se produce un error en tiempo de compilación. El entorno de compilación también puede crear un método de punto de entrada si no existe uno.
Cuando comienza un programa, si el punto de entrada tiene un parámetro, el argumento proporcionado por el entorno de ejecución contiene los argumentos de la línea de comandos para el programa representado como cadenas. Si el punto de entrada tiene un tipo de valor devuelto de Integer, el valor devuelto de la función se devuelve al entorno de ejecución como resultado del programa.
En todos los demás aspectos, los métodos de punto de entrada se comportan de la misma manera que otros métodos. Cuando la ejecución deja la invocación del método de punto de entrada realizado por el entorno de ejecución, el programa finaliza.
Opciones de compilación
Un archivo de origen puede especificar opciones de compilación en el código fuente mediante instrucciones option.
OptionStatement
: OptionExplicitStatement
| OptionStrictStatement
| OptionCompareStatement
| OptionInferStatement
;
Una Option instrucción solo se aplica al archivo de origen en el que aparece y solo puede aparecer uno de cada tipo de instrucción en un archivo de Option origen. Por ejemplo:
Option Strict On
Option Compare Text
Option Strict Off ' Not allowed, Option Strict is already specified.
Option Compare Text ' Not allowed, Option Compare is already specified.
Hay cuatro opciones de compilación: semántica de tipos estrictas, semántica de declaraciones explícitas, semántica de comparación y semántica de inferencia de tipos locales. Si un archivo de origen no incluye una instrucción determinada Option , el entorno de compilación determina qué conjunto determinado de semántica se usará. También hay una quinta opción de compilación, comprobaciones de desbordamiento de enteros, que solo se pueden especificar a través del entorno de compilación.
Option Explicit (instrucción)
La Option Explicit instrucción determina si las variables locales se pueden declarar implícitamente. Las palabras clave On o Off pueden seguir la instrucción ; si no se especifica ninguna, el valor predeterminado es On. Si no se especifica ninguna instrucción en un archivo, el entorno de compilación determina cuál se usará.
OptionExplicitStatement
: 'Option' 'Explicit' OnOff? StatementTerminator
;
OnOff
: 'On' | 'Off'
;
Nota.
Explicit y Off no son palabras reservadas.
Option Explicit Off
Module Test
Sub Main()
x = 5 ' Valid because Option Explicit is off.
End Sub
End Module
En este ejemplo, la variable x local se declara implícitamente mediante la asignación a ella. El tipo de x es Object.
Option Strict (instrucción)
La Option Strict instrucción determina si las conversiones y las operaciones en Object se rigen por una semántica de tipo estricta o permisiva y si los tipos se escriben implícitamente como Object si no se especifica ninguna As cláusula. La instrucción puede ir seguida de las palabras clave On o Off; si no se especifica ninguna, el valor predeterminado es On. Si no se especifica ninguna instrucción en un archivo, el entorno de compilación determina cuál se usará.
OptionStrictStatement
: 'Option' 'Strict' OnOff? StatementTerminator
;
Nota.
Strict y Off no son palabras reservadas.
Option Strict On
Module Test
Sub Main()
Dim x ' Error, no type specified.
Dim o As Object
Dim b As Byte = o ' Error, narrowing conversion.
o.F() ' Error, late binding disallowed.
o = o + 1 ' Error, addition is not defined on Object.
End Sub
End Module
En semántica estricta, no se permiten lo siguiente:
Conversión de restricción sin un operador de conversión explícito.
Enlace en tiempo de demora.
Operaciones en el tipo
Objectdistinto deTypeOf...Is,IsyIsNot.Omitir la
Ascláusula en una declaración que no tiene un tipo inferido.
Option Compare (instrucción)
La Option Compare instrucción determina la semántica de las comparaciones de cadenas. Las comparaciones de cadenas se realizan mediante comparaciones binarias (en las que se compara el valor Unicode binario de cada carácter) o comparaciones de texto (en las que se compara el significado léxico de cada carácter mediante la referencia cultural actual). Si no se especifica ninguna instrucción en un archivo, el entorno de compilación controla qué tipo de comparación se usará.
OptionCompareStatement
: 'Option' 'Compare' CompareOption StatementTerminator
;
CompareOption
: 'Binary' | 'Text'
;
Note.Compare, Binary, y Text no son palabras reservadas.
Option Compare Text
Module Test
Sub Main()
Console.WriteLine("a" = "A") ' Prints True.
End Sub
End Module
En este caso, la comparación de cadenas se realiza mediante una comparación de texto que omite las diferencias entre mayúsculas y minúsculas. Si Option Compare Binary se hubiera especificado, esto habría impreso False.
Comprobaciones de desbordamiento de enteros
Las operaciones de entero se pueden comprobar o no comprobar las condiciones de desbordamiento en tiempo de ejecución. Si se comprueban las condiciones de desbordamiento y se desborda una operación de entero, se produce una System.OverflowException excepción. Si no se comprueban las condiciones de desbordamiento, los desbordamientos de la operación de enteros no inician una excepción. El entorno de compilación determina si esta opción está activada o desactivada.
Option Infer (instrucción)
La Option Infer instrucción determina si las declaraciones de variables locales que no tienen ninguna As cláusula tienen un tipo inferido o usan Object. La instrucción puede ir seguida de las palabras clave On o Off; si no se especifica ninguna, el valor predeterminado es On. Si no se especifica ninguna instrucción en un archivo, el entorno de compilación determina cuál se usará.
OptionInferStatement
: 'Option' 'Infer' OnOff? StatementTerminator
;
Nota.
Infer y Off no son palabras reservadas.
Option Infer On
Module Test
Sub Main()
' The type of x is Integer
Dim x = 10
' The type of y is String
Dim y = "abc"
End Sub
End Module
Imports (instrucción)
Imports las instrucciones importan los nombres de las entidades en un archivo de origen, lo que permite hacer referencia a los nombres sin cualificación o importar un espacio de nombres para su uso en expresiones XML.
ImportsStatement
: 'Imports' ImportsClauses StatementTerminator
;
ImportsClauses
: ImportsClause ( Comma ImportsClause )*
;
ImportsClause
: AliasImportsClause
| MembersImportsClause
| XMLNamespaceImportsClause
;
Dentro de las declaraciones de miembro de un archivo de origen que contiene una Imports instrucción , se puede hacer referencia directamente a los tipos contenidos en el espacio de nombres especificado, como se muestra en el ejemplo siguiente:
Imports N1.N2
Namespace N1.N2
Class A
End Class
End Namespace
Namespace N3
Class B
Inherits A
End Class
End Namespace
Aquí, dentro del archivo de origen, los miembros de tipo del espacio de nombres N1.N2 están disponibles directamente y, por tanto, la clase N3.B deriva de la clase N1.N2.A.
Imports Las instrucciones deben aparecer después de las Option instrucciones, pero antes de cualquier declaración de tipo. El entorno de compilación también puede definir instrucciones implícitas Imports .
Imports las instrucciones hacen que los nombres estén disponibles en un archivo de origen, pero no declaren nada en el espacio de declaración del espacio de nombres global. El ámbito de los nombres importados por una Imports instrucción se extiende a través de las declaraciones de miembro del espacio de nombres contenidas en el archivo de origen. El ámbito de una Imports instrucción específicamente no incluye otras Imports instrucciones, ni incluye otros archivos de código fuente.
Imports Las instrucciones pueden no referirse entre sí.
En este ejemplo, la última Imports instrucción está en error porque no se ve afectada por el primer alias de importación.
Imports R1 = N1 ' OK.
Imports R2 = N1.N2 ' OK.
Imports R3 = R1.N2 ' Error: Can't refer to R1.
Namespace N1.N2
End Namespace
Nota. Los nombres de tipo o espacio de nombres que aparecen en Imports instrucciones siempre se tratan como si fueran completos. Es decir, el identificador más a la izquierda de un espacio de nombres o un nombre de tipo siempre se resuelve en el espacio de nombres global y el resto de la resolución continúa según las reglas normales de resolución de nombres. Este es el único lugar en el idioma que aplica dicha regla; la regla garantiza que un nombre no se puede ocultar completamente de la calificación. Sin la regla, si un nombre en el espacio de nombres global estuviera oculto en un archivo de origen determinado, sería imposible especificar nombres de ese espacio de nombres de forma calificada.
En este ejemplo, la Imports instrucción siempre hace referencia al espacio de nombres global System y no a la clase del archivo de origen.
Imports System ' Imports the namespace, not the class.
Class System
End Class
Importar alias
Un alias de importación define un alias para un espacio de nombres o un tipo.
AliasImportsClause
: Identifier Equals TypeName
;
Imports A = N1.N2.A
Namespace N1.N2
Class A
End Class
End Namespace
Namespace N3
Class B
Inherits A
End Class
End Namespace
Aquí, dentro del archivo de origen, es un alias para N1.N2.Ay, por tanto, A la clase N3.B deriva de la clase N1.N2.A. El mismo efecto se puede obtener creando un alias R para N1.N2 y haciendo referencia a R.A:
Imports R = N1.N2
Namespace N3
Class B
Inherits R.A
End Class
End Namespace
El identificador de un alias de importación debe ser único dentro del espacio de declaraciones del espacio de nombres global (no solo la declaración de espacio de nombres global en el archivo de origen en el que se define el alias de importación), aunque no declare un nombre en el espacio de declaración del espacio de nombres global.
Nota. Las declaraciones de un módulo no introducen nombres en el espacio de declaración contenedor. Por lo tanto, es válido para que una declaración de un módulo tenga el mismo nombre que un alias de importación, aunque el nombre de la declaración sea accesible en el espacio de declaración contenedor.
' Error: Alias A conflicts with typename A
Imports A = N3.A
Class A
End Class
Namespace N3
Class A
End Class
End Namespace
Aquí, el espacio de nombres global ya contiene un miembro A, por lo que es un error para que un alias de importación use ese identificador. Del mismo modo, es un error para dos o más alias de importación en el mismo archivo de origen para declarar alias por el mismo nombre.
Un alias de importación puede crear un alias para cualquier espacio de nombres o tipo. El acceso a un espacio de nombres o un tipo a través de un alias produce exactamente el mismo resultado que el acceso al espacio de nombres o al tipo a través de su nombre declarado.
Imports R1 = N1
Imports R2 = N1.N2
Namespace N1.N2
Class A
End Class
End Namespace
Namespace N3
Class B
Private a As N1.N2.A
Private b As R1.N2.A
Private c As R2.A
End Class
End Namespace
Aquí, los nombres N1.N2.A, R1.N2.Ay son equivalentes, y R2.A todos hacen referencia a la clase cuyo nombre completo es N1.N2.A.
La importación especifica el nombre exacto del espacio de nombres o el tipo al que está creando un alias. Debe ser el nombre completo exacto de ese espacio de nombres o tipo: no usa las reglas normales para la resolución de nombres calificada (que, por ejemplo, permiten el acceso a los miembros de una clase base a través de una clase derivada).
Si un alias de importación apunta a un tipo o espacio de nombres que estas reglas no pueden resolver, se omite la instrucción import (y el compilador emite una advertencia).
Además, la referencia no puede ser a un tipo genérico abierto: todos los tipos genéricos deben tener argumentos de tipo válidos proporcionados y todas las reglas anteriores deben resolver todos los argumentos de tipo. Cualquier enlace incorrecto de un tipo genérico es un error.
Imports A = G ' error: since G is an open generic type
Imports B = G(Of Integer) ' okay
Imports C = Derived.Nested ' warning: Derived.Nested isn't itself a type
Imports D = G(Of Derived.Nested) ' error: Derived.Nested isn't found
Class G(Of T) : End Class
Class Base
Class Nested : End Class
End Class
Class Derived : Inherits Base
End Class
Module Module1
Sub Main()
Dim x As C ' error: "C" wasn't succesfully defined
Dim y As Derived.Nested ' okay
End Sub
End Module
Las declaraciones del archivo de origen pueden sombrar el nombre del alias de importación.
Imports R = N1.N2
Namespace N1.N2
Class A
End Class
End Namespace
Namespace N3
Class R
End Class
Class B
Inherits R.A ' Error, R has no member A
End Class
End Namespace
En el ejemplo anterior, la referencia a R.A en la declaración de B produce un error porque R hace referencia a N3.R, no N1.N2a .
Un alias de importación hace que un alias esté disponible dentro de un archivo de origen determinado, pero no contribuye a ningún nuevo miembro al espacio de declaración subyacente. En otras palabras, un alias de importación no es transitivo, sino que afecta solo al archivo de origen en el que se produce.
File1.vb:
Imports R = N1.N2
Namespace N1.N2
Class A
End Class
End Namespace
File2.vb:
Class B
Inherits R.A ' Error, R unknown.
End Class
En el ejemplo anterior, dado que el ámbito del alias de importación que introduce R solo se extiende a las declaraciones del archivo de origen en el que está contenido, R se desconoce en el segundo archivo de origen.
Importaciones de espacio de nombres
Un espacio de nombres importa todos los miembros de un espacio de nombres o un tipo, lo que permite usar el identificador de cada miembro del espacio de nombres o el tipo sin cualificación. En el caso de los tipos, una importación de espacio de nombres solo permite el acceso a los miembros compartidos del tipo sin necesidad de cualificación del nombre de clase. En concreto, permite que los miembros de los tipos enumerados se usen sin cualificación.
MembersImportsClause
: TypeName
;
Por ejemplo:
Imports Colors
Enum Colors
Red
Green
Blue
End Enum
Module M1
Sub Main()
Dim c As Colors = Red
End Sub
End Module
A diferencia de un alias de importación, una importación de espacio de nombres no tiene restricciones en los nombres que importa y puede importar espacios de nombres y tipos cuyos identificadores ya están declarados en el espacio de nombres global. Los nombres importados por una importación normal son sombreados por alias de importación y declaraciones en el archivo de origen.
En el ejemplo siguiente, A hace referencia a N3.A en lugar de N1.N2.A en declaraciones de miembro en el N3 espacio de nombres .
Imports N1.N2
Namespace N1.N2
Class A
End Class
End Namespace
Namespace N3
Class A
End Class
Class B
Inherits A
End Class
End Namespace
Cuando más de un espacio de nombres importado contiene miembros con el mismo nombre (y ese nombre no está sombreado por un alias o declaración de importación), una referencia a ese nombre es ambigua y provoca un error en tiempo de compilación.
Imports N1
Imports N2
Namespace N1
Class A
End Class
End Namespace
Namespace N2
Class A
End Class
End Namespace
Namespace N3
Class B
Inherits A ' Error, A is ambiguous.
End Class
End Namespace
En el ejemplo anterior, y N1N2 contienen un miembro A. Dado que N3 importa ambos, hacer referencia A a en provoca un error en N3 tiempo de compilación. En esta situación, el conflicto se puede resolver a través de la calificación de referencias a Ao mediante la introducción de un alias de importación que elige un determinado A, como en el ejemplo siguiente:
Imports N1
Imports N2
Imports A = N1.A
Namespace N3
Class B
Inherits A ' A means N1.A.
End Class
End Namespace
Solo se pueden importar espacios de nombres, clases, estructuras, tipos enumerados y módulos estándar.
Importaciones de espacios de nombres XML
Una importación de espacio de nombres XML define un espacio de nombres o el espacio de nombres predeterminado para expresiones XML no calificadas contenidas en la unidad de compilación.
XMLNamespaceImportsClause
: '<' XMLNamespaceAttributeName XMLWhitespace? Equals XMLWhitespace?
XMLNamespaceValue '>'
;
XMLNamespaceValue
: DoubleQuoteCharacter XMLAttributeDoubleQuoteValueCharacter* DoubleQuoteCharacter
| SingleQuoteCharacter XMLAttributeSingleQuoteValueCharacter* SingleQuoteCharacter
;
Por ejemplo:
Imports <xmlns:db="http://example.org/database">
Module Test
Sub Main()
' db namespace is "http://example.org/database"
Dim x = <db:customer><db:Name>Bob</></>
Console.WriteLine(x.<db:Name>)
End Sub
End Module
Un espacio de nombres XML, incluido el espacio de nombres predeterminado, solo se puede definir una vez para un conjunto determinado de importaciones. Por ejemplo:
Imports <xmlns:db="http://example.org/database-one">
' Error: namespace db is already defined
Imports <xmlns:db="http://example.org/database-two">
Espacios de nombres
Los programas de Visual Basic se organizan mediante espacios de nombres. Los espacios de nombres organizan internamente un programa, así como la forma en que los elementos del programa se exponen a otros programas.
A diferencia de otras entidades, los espacios de nombres están abiertos y se pueden declarar varias veces dentro del mismo programa y en muchos programas, con cada declaración que contribuye a los miembros al mismo espacio de nombres. En el ejemplo siguiente, las dos declaraciones de espacio de nombres contribuyen al mismo espacio de declaración, declarando dos clases con los nombres N1.N2.A completos y N1.N2.B.
Namespace N1.N2
Class A
End Class
End Namespace
Namespace N1.N2
Class B
End Class
End Namespace
Dado que las dos declaraciones contribuyen al mismo espacio de declaración, sería un error si cada una contenía una declaración de un miembro con el mismo nombre.
Hay un espacio de nombres global que no tiene ningún nombre y cuyos espacios de nombres anidados y tipos siempre se pueden tener acceso sin calificación. El ámbito de un miembro de espacio de nombres declarado en el espacio de nombres global es todo el texto del programa. De lo contrario, el ámbito de un tipo o espacio de nombres declarado en un espacio de nombres cuyo nombre completo es N el texto del programa de cada espacio de nombres cuyo nombre completo correspondiente comienza por N o por N sí mismo. (Tenga en cuenta que un compilador puede elegir colocar declaraciones en un espacio de nombres determinado de forma predeterminada. Esto no modifica el hecho de que todavía hay un espacio de nombres global sin nombre).
En este ejemplo, la clase B puede ver la clase A porque Bel espacio de nombres N1.N2.N3 está anidado conceptualmente dentro del espacio de nombres N1.N2.
Namespace N1.N2
Class A
End Class
End Namespace
Namespace N1.N2.N3
Class B
Inherits A
End Class
End Namespace
Declaraciones de espacios de nombres
Hay tres formas de declaración de espacio de nombres.
NamespaceDeclaration
: 'Namespace' NamespaceName StatementTerminator
NamespaceMemberDeclaration*
'End' 'Namespace' StatementTerminator
;
NamespaceName
: RelativeNamespaceName
| 'Global'
| 'Global' '.' RelativeNamespaceName
;
RelativeNamespaceName
: Identifier ( Period IdentifierOrKeyword )*
;
El primer formulario comienza con la palabra clave Namespace seguida de un nombre de espacio de nombres relativo. Si el nombre del espacio de nombres relativo está calificado, la declaración de espacio de nombres se trata como si estuviera anidada léxicamente dentro de las declaraciones de espacio de nombres correspondientes a cada nombre en el nombre completo. Por ejemplo, los dos espacios de nombres siguientes son semánticamente equivalentes:
Namespace N1.N2
Class A
End Class
Class B
End Class
End Namespace
Namespace N1
Namespace N2
Class A
End Class
Class B
End Class
End Namespace
End Namespace
El segundo formulario comienza con las palabras clave Namespace Global. Se trata como si todas sus declaraciones de miembro se colocaran léxicamente en el espacio de nombres global sin nombre, independientemente de los valores predeterminados proporcionados por el entorno de compilación. Esta forma de declaración de espacio de nombres puede no estar anidada léxicamente dentro de ninguna otra declaración de espacio de nombres.
El tercer formulario comienza con las palabras clave Namespace Global seguidas de un identificador Ncompleto. Se trata como si fuera una declaración de espacio de nombres de la primera forma "Namespace N" que se colocó léxicamente en el espacio de nombres global sin nombre, independientemente de los valores predeterminados proporcionados por el entorno de compilación. Esta forma de declaración de espacio de nombres puede no estar anidada léxicamente dentro de ninguna otra declaración de espacio de nombres.
Namespace Global ' Puts N1.A in the global namespace
Namespace N1
Class A
End Class
End Namespace
End Namespace
Namespace Global.N1 ' Equivalent to the above
Class A
End Class
End Namespace
Namespace N1 ' May or may not be equivalent to the above,
Class A ' depending on defaults provided by the
End Class ' compilation environment
End Namespace
Cuando se trabaja con los miembros de un espacio de nombres, no es importante cuando se declara un miembro determinado. Si dos programas definen una entidad con el mismo nombre en el mismo espacio de nombres, al intentar resolver el nombre en el espacio de nombres se produce un error de ambigüedad.
Los espacios de nombres son por definición Public, por lo que una declaración de espacio de nombres no puede incluir ningún modificador de acceso.
Miembros del espacio de nombres
Los miembros del espacio de nombres solo pueden ser declaraciones de espacio de nombres y declaraciones de tipo. Las declaraciones de tipo pueden tener Public o Friend tener acceso. El acceso predeterminado para los tipos es Friend el acceso.
NamespaceMemberDeclaration
: NamespaceDeclaration
| TypeDeclaration
;
TypeDeclaration
: ModuleDeclaration
| NonModuleDeclaration
;
NonModuleDeclaration
: EnumDeclaration
| StructureDeclaration
| InterfaceDeclaration
| ClassDeclaration
| DelegateDeclaration
;
Visual Basic language spec