Compartir a través de


Inicializadores de objeto: Tipos con nombre y anónimos

Actualización: noviembre 2007

Los inicializadores de objeto permiten especificar las propiedades de un objeto complejo mediante una sola expresión. Se pueden usar para crear instancias de tipos con nombre y tipos anónimos.

Declaraciones

Las declaraciones de instancias de tipos con nombre y anónimos pueden parecer casi idénticas, pero su aplicación no es la misma. Cada categoría tiene funcionalidades y restricciones propias. El ejemplo siguiente muestra una forma adecuada de declarar e inicializar una instancia de una clase con nombre, Customer, mediante un lista de inicializadores de objeto. Observe que el nombre de la clase se especifica después de la palabra clave New.

Dim namedCust = New Customer With {.Name = "Terry Adams"}

Un tipo anónimo no tiene ningún nombre que se pueda usar. Por consiguiente, una creación de instancias de un tipo anónimo no puede incluir un nombre de clase.

Dim anonymousCust = New With {.Name = "Hugo Garcia"}

Los requisitos y resultados de las dos declaraciones no son los mismos. En namedCust, ya debe existir una clase Customer con una propiedad Name y la declaración crea una instancia de la clase. En anonymousCust, el compilador define una nueva clase que tiene una propiedad, una cadena denominada Name y crea una nueva instancia de esa clase.

Tipos con nombre

Los inicializadores de objeto proporcionan una forma sencilla de llamar al constructor de un tipo y, a continuación, establecer los valores de algunas o de todas las propiedades en una sola instrucción. El compilador invoca al constructor adecuado de la instrucción: el constructor predeterminado si no hay argumentos o un constructor con parámetros si se envían uno o más argumentos. Después, se inicializan las propiedades especificadas en el orden en que aparecen en la lista de inicializadores.

Cada inicialización de la lista de inicializadores está formada por la asignación de un valor inicial a un miembro de la clase. Se determinan los nombres y los tipos de datos de los miembros cuando se define la clase. En los ejemplos siguientes, la clase Customer debe existir y debe tener miembros denominados Name y City que pueden aceptar valores de cadena.

Dim cust0 As Customer = New Customer With {.Name = "Toni Poe", _
                                           .City = "Louisville"}

O bien, puede obtener el mismo resultado utilizando el código siguiente:

Dim cust1 As New Customer With {.Name = "Toni Poe", _
                                .City = "Louisville"}

Cada una de estas declaraciones es equivalente al siguiente ejemplo, que crea un objeto Customer mediante el constructor predeterminado y, a continuación, especifica los valores iniciales de las propiedades Name y City mediante el uso de una instrucción With.

Dim cust2 As New Customer()
With cust2
    .Name = "Toni Poe"
    .City = "Louisville"
End With

Si la clase Customer contiene un constructor con parámetros que permita enviar un valor de Name, por ejemplo, también puede declarar e inicializar un objeto Customer de las siguientes formas:

Dim cust3 As Customer = New Customer("Toni Poe") _
    With {.City = "Louisville"}
' --or--
Dim cust4 As New Customer("Toni Poe") _
    With {.City = "Louisville"}

No debe inicializar todas las propiedades, como muestra el código siguiente.

Dim cust5 As Customer = New Customer With {.Name = "Toni Poe"}

Sin embargo, la lista de inicializaciones no puede estar vacía. Las propiedades sin inicializar conservan sus valores predeterminados.

Inferencia de tipo con tipos con nombre

Puede acortar el código de la declaración de cust1 combinando los inicializadores de objeto y la inferencia de tipo de variable local. De esta forma, puede pasar por alto la cláusula As en la declaración de variable. El tipo de datos de la variable se deduce del tipo del objeto que se crea mediante la asignación. En el ejemplo siguiente, el tipo de cust6 es Customer.

Dim cust6 = New Customer With {.Name = "Toni Poe", _
                               .City = "Louisville"}

Comentarios sobre los tipos con nombre

  • Un miembro de clase sólo se puede inicializar una vez en la lista de inicializadores de objeto. La declaración de cust7 provoca un error.

    '' This code does not compile because Name is initialized twice.
    ' Dim cust7 = New Customer With {.Name = "Toni Poe", _
    '                                .City = "Louisville" _
    '                                .Name = "Blue Yonder Airlines"}
    
  • Un miembro se puede usar para inicializarse a sí mismo o a otro campo. Si se tiene acceso a un miembro antes de haberse inicializado, como ocurre en la declaración siguiente de cust8, se usará el valor predeterminado. Recuerde que cuando se procesa una declaración con un inicializador de objeto, lo primero que ocurre es que se invoca el constructor adecuado. Después, se inicializan los campos individuales de la lista de inicializadores. En los ejemplos siguientes, el valor predeterminado de Name se asigna para cust8 y se asigna un valor inicializado de cust9.

    Dim cust8 = New Customer With {.Name = .Name & ", President"}
    Dim cust9 = New Customer With {.Name = "Toni Poe", _
                                   .Title = .Name & ", President"}
    

    El ejemplo siguiente utiliza el constructor con parámetros de cust3 y cust4 para declarar e inicializar cust10 y cust11.

    Dim cust10 = New Customer("Toni Poe") With {.Name = .Name & ", President"}
    ' --or--
    Dim cust11 As New Customer("Toni Poe") With {.Name = .Name & ", President"}
    
  • Los inicializadores de objeto pueden estar anidados. En el ejemplo siguiente, AddressClass es una clase que tiene dos propiedades, City y State, y la clase Customer tiene una propiedad Address que es una instancia de AddressClass.

    Dim cust12 = New Customer With {.Name = "Toni Poe", _
                                    .Address = New AddressClass _
                                    With {.City = "Louisville", _
                                          .State = "Kentucky"}}
    Console.WriteLine(cust12.Address.State)
    
  • La lista de inicializaciones no puede estar vacía.

  • La instancia que se inicializa no puede ser de tipo Object.

  • Los miembros de clase que se inicializan no pueden ser miembros compartidos, miembros de sólo lectura, constantes ni llamadas a métodos.

  • Los miembros de clase que se inicializan no se pueden indizar ni certificar. Los ejemplos siguientes provocan errores del compilador:

    '' Not valid.

    ' Dim c1 = New Customer With {.OrderNumbers(0) = 148662}

    ' Dim c2 = New Customer with {.Address.City = "Springfield"}

Tipos anónimos

Los tipos anónimos usan inicializadores de objetos para crear instancias de tipos nuevos que el usuario no define ni a los que les asigna nombres explícitamente. En su lugar, el compilador genera un tipo según las propiedades designadas en la lista de inicializadores de objeto. Puesto que no se especifica el nombre del tipo, se hace referencia a él como tipo anónimo. Por ejemplo, compare la declaración siguiente con la anterior de cust6.

Dim cust13 = New With {.Name = "Toni Poe", _
                       .City = "Louisville"}

La única diferencia sintácticamente es que no se especifica ningún nombre detrás de New para el tipo de datos. Sin embargo, lo que ocurre es muy diferente. El compilador define un nuevo tipo anónimo con dos propiedades, Name y City, y crea una instancia de él con los valores especificados. La inferencia de tipo determina los tipos de Name y City del ejemplo para que sean cadenas.

Precaución:

El compilador genera el nombre del tipo anónimo y quizá cambie de una compilación a otra. El código no debe usar el nombre de un tipo anónimo ni depender de él.

Dado que el nombre del tipo no está disponible, no puede utilizar una cláusula As para declarar cust13. Se debe deducir su tipo. Si no se usa el enlace en tiempo de ejecución, se limita el uso de tipos anónimos en variables locales.

Los tipos anónimos proporcionan la compatibilidad crítica de las consultas LINQ. Para obtener más información sobre el uso de tipos anónimos en consultas, vea Tipos anónimos e Introducción a LINQ en Visual Basic.

Comentarios sobre tipos anónimos

  • Normalmente, todas o la mayoría de las propiedades de una declaración de tipos anónimos serán propiedades de clave, lo que se indica escribiendo la palabra clave Key delante del nombre de la propiedad.

    Dim anonymousCust1 = New With {Key .Name = "Hugo Garcia", _
                                   Key .City = "Louisville"}
    

    Para obtener más información sobre propiedades de clave, vea Key (Visual Basic).

  • Como ocurre con los tipos con nombre, las listas de inicializadores de las definiciones de tipo anónimo debe declarar al menos una propiedad.

    Dim anonymousCust = New With {.Name = "Hugo Garcia"}
    
  • Cuando se declara una instancia de un tipo anónimo, el compilador genera una definición de tipo anónimo coincidente. Los nombres y tipos de datos de las propiedades se toman de la declaración de la instancia y el compilador los incluye en la definición. A las propiedades no se les asigna nombre ni se definen de antemano, como ocurriría con un tipo con nombre. Se deducen sus tipos. No puede especificar los tipos de datos de las propiedades utilizando una cláusula As.

  • Los tipos anónimos también pueden establecer los nombres y valores de sus propiedades de otras maneras distintas. Por ejemplo, una propiedad de tipo anónimo puede tomar tanto el nombre como el valor de una variable o el nombre y valor de una propiedad de otro objeto.

    ' Create a variable, Name, and give it an initial value.
    Dim Name = "Hugo Garcia"
    
    ' Variable anonymousCust2 will have one property, Name, with 
    ' "Hugo Garcia" as its initial value.
    Dim anonymousCust2 = New With {Key Name}
    
    ' The next declaration uses a property from namedCust, defined
    ' in an earlier example. After the declaration, anonymousCust3 will
    ' have one property, Name, with "Terry Adams" as its value.
    Dim anonymousCust3 = New With {Key namedCust.Name}
    

    Para obtener más información sobre las opciones para definir propiedades de tipos anónimos, vea Cómo: Deducir tipos y nombres de propiedades en declaraciones de tipos anónimos.

Vea también

Tareas

Cómo: Deducir tipos y nombres de propiedades en declaraciones de tipos anónimos

Cómo: Declarar una instancia de un tipo anónimo

Cómo: Declarar un objeto usando un inicializador de objeto

Conceptos

Inferencia de tipo de variable local

Tipos anónimos

Introducción a LINQ en Visual Basic

Tipos con nombre y anónimos comparados

Referencia

Key (Visual Basic)