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.
Visual Basic admite tipos anónimos, que permiten crear objetos sin escribir una definición de clase para el tipo de datos. En su lugar, el compilador genera una clase automáticamente. La clase no tiene ningún nombre utilizable, hereda directamente de Objecty contiene las propiedades especificadas para declarar el objeto. Dado que no se especifica el nombre del tipo de datos, se conoce como un tipo anónimo.
En el ejemplo siguiente se declara y se crea una variable product
como una instancia de un tipo anónimo que tiene dos propiedades y Name
Price
.
' Variable product is an instance of a simple anonymous type.
Dim product = New With {Key .Name = "paperclips", .Price = 1.29}
Una expresión de consulta usa tipos anónimos para combinar columnas de datos seleccionados por una consulta. No se puede definir el tipo de resultado de antemano, ya que no se pueden predecir las columnas que puede seleccionar una consulta determinada. Los tipos anónimos permiten escribir una consulta que seleccione cualquier número de columnas, en cualquier orden. El compilador crea un tipo de datos que coincide con las propiedades especificadas y el orden especificado.
En los ejemplos siguientes, products
es una lista de objetos de producto, cada uno de los cuales tiene muchas propiedades. Variable namePriceQuery
contiene la definición de una consulta que, cuando se ejecuta, devuelve una colección de instancias de un tipo anónimo que tiene dos propiedades Name
y Price
.
Dim namePriceQuery = From prod In products
Select prod.Name, prod.Price
Variable nameQuantityQuery
contiene la definición de una consulta que, cuando se ejecuta, devuelve una colección de instancias de un tipo anónimo que tiene dos propiedades Name
y OnHand
.
Dim nameQuantityQuery = From prod In products
Select prod.Name, prod.OnHand
Para obtener más información sobre el código creado por el compilador para un tipo anónimo, vea Definición de tipos anónimos.
Precaución
El nombre del tipo anónimo es generado por el compilador y puede variar de una compilación a otra. El código no debe usar ni confiar en el nombre de un tipo anónimo porque el nombre puede cambiar cuando se vuelve a compilar un proyecto.
Declarar un tipo anónimo
La declaración de una instancia de un tipo anónimo usa una lista de inicializadores para especificar las propiedades del tipo. Solo puede especificar propiedades al declarar un tipo anónimo, no otros elementos de clase como métodos o eventos. En el ejemplo siguiente, product1
es una instancia de un tipo anónimo que tiene dos propiedades: Name
y Price
.
' Variable product1 is an instance of a simple anonymous type.
Dim product1 = New With {.Name = "paperclips", .Price = 1.29}
' -or-
' product2 is an instance of an anonymous type with key properties.
Dim product2 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Si designa propiedades como propiedades clave, puede usarlas para comparar dos instancias de tipo anónimo para obtener igualdad. Sin embargo, los valores de las propiedades clave no se pueden cambiar. Consulte la sección Propiedades de clave más adelante en este tema para obtener más información.
Observe que declarar una instancia de un tipo anónimo es como declarar una instancia de un tipo con nombre mediante un inicializador de objeto:
' Variable product3 is an instance of a class named Product.
Dim product3 = New Product With {.Name = "paperclips", .Price = 1.29}
Para obtener más información sobre otras formas de especificar propiedades de tipo anónimo, vea How to: Infer Property Names and Types in Anonymous Type Declarations.
Propiedades importantes
Las propiedades clave difieren de las propiedades que no son clave de varias maneras fundamentales:
Solo se comparan los valores de las propiedades clave para determinar si dos instancias son iguales.
Los valores de las propiedades clave son de solo lectura y no se pueden cambiar.
Solo se incluyen los valores clave de las propiedades en el algoritmo de código hash generado por el compilador para un tipo anónimo.
Igualdad
Las instancias de tipos anónimos solo pueden ser iguales si son instancias del mismo tipo anónimo. El compilador trata dos instancias como instancias del mismo tipo si cumplen las condiciones siguientes:
Se declaran en el mismo ensamblado.
Sus propiedades tienen los mismos nombres, los mismos tipos inferidos y se declaran en el mismo orden. Las comparaciones de nombres no distinguen mayúsculas de minúsculas.
Las mismas propiedades de cada una se marcan como propiedades clave.
Al menos una propiedad de cada declaración es una propiedad clave.
Una instancia de un tipo anónimo que no tiene propiedades clave es igual a sí misma.
' prod1 and prod2 have no key values.
Dim prod1 = New With {.Name = "paperclips", .Price = 1.29}
Dim prod2 = New With {.Name = "paperclips", .Price = 1.29}
' The following line displays False, because prod1 and prod2 have no
' key properties.
Console.WriteLine(prod1.Equals(prod2))
' The following statement displays True because prod1 is equal to itself.
Console.WriteLine(prod1.Equals(prod1))
Dos instancias del mismo tipo anónimo son iguales si los valores de sus propiedades clave son iguales. En los ejemplos siguientes se muestra cómo se prueba la igualdad.
Dim prod3 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim prod4 = New With {Key .Name = "paperclips", Key .Price = 1.29}
' The following line displays True, because prod3 and prod4 are
' instances of the same anonymous type, and the values of their
' key properties are equal.
Console.WriteLine(prod3.Equals(prod4))
Dim prod5 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim prod6 = New With {Key .Name = "paperclips", Key .Price = 1.29,
.OnHand = 423}
' The following line displays False, because prod5 and prod6 do not
' have the same properties.
Console.WriteLine(prod5.Equals(prod6))
Dim prod7 = New With {Key .Name = "paperclips", Key .Price = 1.29,
.OnHand = 24}
Dim prod8 = New With {Key .Name = "paperclips", Key .Price = 1.29,
.OnHand = 423}
' The following line displays True, because prod7 and prod8 are
' instances of the same anonymous type, and the values of their
' key properties are equal. The equality check does not compare the
' values of the non-key field.
Console.WriteLine(prod7.Equals(prod8))
Valores de solo lectura
No se pueden cambiar los valores de las propiedades clave. Por ejemplo, en prod8
del ejemplo anterior, los campos Name
y Price
son read-only
, pero OnHand
se puede cambiar.
' The following statement will not compile, because Name is a key
' property and its value cannot be changed.
' prod8.Name = "clamps"
' OnHand is not a Key property. Its value can be changed.
prod8.OnHand = 22
Tipos anónimos de expresiones de consulta
Las expresiones de consulta no siempre requieren la creación de tipos anónimos. Cuando sea posible, usan un tipo existente para contener los datos de columna. Esto ocurre cuando la consulta devuelve registros completos del origen de datos o solo un campo de cada registro. En los ejemplos de código siguientes, customers
es una colección de objetos de una Customer
clase. La clase tiene muchas propiedades y puede incluir una o varias de ellas en el resultado de la consulta, en cualquier orden. En los dos primeros ejemplos, no se requiere ningún tipo anónimo porque las consultas seleccionan elementos de tipos con nombre:
custs1
contiene una colección de cadenas, porquecust.Name
es una cadena.Dim custs1 = From cust In customers Select cust.Name
custs2
contiene una colección deCustomer
objetos, porque cada elemento decustomers
es unCustomer
objeto y la consulta selecciona todo el elemento.Dim custs2 = From cust In customers Select cust
Sin embargo, los tipos con nombre adecuados no siempre están disponibles. Es posible que quiera seleccionar nombres y direcciones de cliente para un propósito, números de identificador de cliente y ubicaciones para otro, y nombres de clientes, direcciones e historiales de pedidos para un tercero. Los tipos anónimos permiten seleccionar cualquier combinación de propiedades, en cualquier orden, sin declarar primero un nuevo tipo con nombre para contener el resultado. En su lugar, el compilador crea un tipo anónimo para cada compilación de propiedades. La consulta siguiente selecciona solo el nombre del cliente y el número de identificador de cada Customer
objeto de customers
. Por lo tanto, el compilador crea un tipo anónimo que contiene solo esas dos propiedades.
Dim custs3 = From cust In customers
Select cust.Name, cust.ID
Tanto los nombres como los tipos de datos de las propiedades del tipo anónimo se toman de los argumentos a Select
y cust.Name
cust.ID
. Las propiedades de un tipo anónimo creado por una consulta siempre son propiedades clave. Cuando custs3
se ejecuta en el bucle siguiente For Each
, el resultado es una colección de instancias de un tipo anónimo con dos propiedades clave y Name
ID
.
For Each selectedCust In custs3
Console.WriteLine(selectedCust.ID & ": " & selectedCust.Name)
Next
Los elementos de la colección representados por custs3
están fuertemente tipados, y se puede usar IntelliSense para navegar por las propiedades disponibles y comprobar sus tipos.
Para obtener más información, vea Introducción a LINQ en Visual Basic.
Decidir si usar tipos anónimos
Antes de crear un objeto como una instancia de una clase anónima, considere si es la mejor opción. Por ejemplo, si desea crear un objeto temporal para contener datos relacionados y no necesita otros campos y métodos que una clase completa pueda contener, un tipo anónimo es una buena solución. Los tipos anónimos también son cómodos si desea una selección diferente de propiedades para cada declaración, o si desea cambiar el orden de las propiedades. Sin embargo, si el proyecto incluye varios objetos que tienen las mismas propiedades, en un orden fijo, puede declararlos más fácilmente mediante un tipo con nombre con un constructor de clases. Por ejemplo, con un constructor adecuado, es más fácil declarar varias instancias de una Product
clase que declarar varias instancias de un tipo anónimo.
' Declaring instances of a named type.
Dim firstProd1 As New Product("paperclips", 1.29)
Dim secondProd1 As New Product("desklamp", 28.99)
Dim thirdProd1 As New Product("stapler", 5.09)
' Declaring instances of an anonymous type.
Dim firstProd2 = New With {Key .Name = "paperclips", Key .Price = 1.29}
Dim secondProd2 = New With {Key .Name = "desklamp", Key .Price = 28.99}
Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = 5.09}
Otra ventaja de los tipos con nombre es que el compilador puede detectar un error de escritura accidental en un nombre de propiedad. En los ejemplos anteriores, firstProd2
, secondProd2
y thirdProd2
están diseñados para ser instancias del mismo tipo anónimo. Sin embargo, si se declarara thirdProd2
accidentalmente de una de las siguientes maneras, su tipo sería diferente del de firstProd2
y secondProd2
.
' Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = 5.09}
' Dim thirdProd2 = New With {Key .Name = "stapler", Key .Price = "5.09"}
' Dim thirdProd2 = New With {Key .Name = "stapler", .Price = 5.09}
Lo más importante es que hay limitaciones en el uso de tipos anónimos que no se aplican a instancias de tipos con nombre.
firstProd2
, secondProd2
y thirdProd2
son instancias del mismo tipo anónimo. Sin embargo, el nombre del tipo anónimo compartido no está disponible y no puede aparecer donde se espera un nombre de tipo en el código. Por ejemplo, un tipo anónimo no se puede usar para definir una firma de método, para declarar otra variable o campo, o en cualquier declaración de tipo. Como resultado, los tipos anónimos no son adecuados cuando tiene que compartir información entre métodos.
Definición de tipo anónimo
En respuesta a la declaración de una instancia de un tipo anónimo, el compilador crea una nueva definición de clase que contiene las propiedades especificadas.
Si el tipo anónimo contiene al menos una propiedad de clave, la definición invalida a tres miembros heredados de Object: Equals, GetHashCodey ToString. El código generado para probar la igualdad y determinar el valor de código hash solo tiene en cuenta las propiedades clave. Si el tipo anónimo no contiene ninguna propiedad de clave, solo ToString se invalida. Las propiedades con nombre explícito de un tipo anónimo no pueden entrar en conflicto con estos métodos generados. Es decir, no se puede usar .Equals
, .GetHashCode
o .ToString
para asignar un nombre a una propiedad.
Las definiciones de tipos anónimos que tienen al menos una propiedad de clave también implementan la System.IEquatable<T> interfaz, donde T
es el tipo del tipo anónimo.
Para obtener más información sobre el código creado por el compilador y la funcionalidad de los métodos invalidados, vea Definición de tipo anónimo.