Compartir a través de


Inicializadores de objeto: tipos con nombre y anónimos (Visual Basic)

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

Declaraciones

Las declaraciones de instancias de tipos con nombre y anónimos pueden tener un aspecto casi idéntico, pero sus efectos no son los mismos. Cada categoría tiene capacidades y restricciones propias. En el ejemplo siguiente se muestra una manera cómoda de declarar e inicializar una instancia de una clase con nombre, Customer, mediante una lista de inicializadores de objetos. 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 utilizable. Por lo tanto, la instanciación de un tipo anónimo no puede incluir un nombre de clase.

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

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

Tipos con nombre

Los inicializadores de objeto proporcionan una manera sencilla de llamar al constructor de un tipo y, a continuación, establecer los valores de algunas o todas las propiedades de una sola instrucción. El compilador invoca el constructor adecuado para la instrucción : el constructor sin parámetros si no se presenta ningún argumento o un constructor con parámetros si se envían uno o varios argumentos. Después de eso, las propiedades especificadas se inicializan en el orden en que se presentan en la lista de inicializadores.

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

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

Como alternativa, puede obtener el mismo resultado mediante el código siguiente:

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

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

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

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

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

No es necesario inicializar todas las propiedades, como se muestra en el código siguiente.

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

Sin embargo, la lista de inicialización no puede estar vacía. Las propiedades no inicializadas conservan sus valores predeterminados.

Inferencia de tipos en los tipos con nombre

Puede acortar el código para la declaración de cust1 mediante la combinación de inicializadores de objetos e inferencia de tipos locales. Esto le permite omitir la As cláusula en la declaración de variable. El tipo de datos de la variable se deduce del tipo del objeto creado por 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 nombrados

  • Un miembro de clase no se puede inicializar más de una vez en la lista de inicializadores de objetos. La declaración de cust7 produce 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 u a otro campo. Si se accede a un miembro antes de que haya sido inicializado, como en la siguiente declaración para cust8, se usará el valor predeterminado. Recuerde que cuando se procesa una declaración que usa un inicializador de objeto, lo primero que sucede es que se invoca el constructor adecuado. Después, se inicializan los campos individuales de la lista de inicializadores. En los ejemplos siguientes, se asigna el valor predeterminado de Name para cust8y se asigna un valor inicializado en cust9.

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

    En el ejemplo siguiente se usa el constructor parametrizado 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 objetos se pueden anidar. En el ejemplo siguiente, AddressClass es una clase que tiene dos propiedades, City y State, y la Customer clase tiene una Address propiedad 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 inicialización 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 solo lectura, constantes o llamadas de método.

  • Los miembros de clase que se inicializan no se pueden indexar ni calificar. En los ejemplos siguientes se producen 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 a los que no ha definido ni asignado un nombre explícitamente. En su lugar, el compilador genera un tipo según las propiedades que designe en la lista de inicializadores de objetos. Dado que no se especifica el nombre del tipo, se conoce como un tipo anónimo. Por ejemplo, compare la siguiente declaración con la anterior para cust6.

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

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

Precaución

El compilador genera el nombre del tipo anónimo y puede variar de compilación a compilación. El código no debe usar ni confiar en el nombre de un tipo anónimo.

Dado que el nombre del tipo no está disponible, no se puede usar una As cláusula para declarar cust13. Su tipo debe inferirse. Sin usar la vinculación tardía, esto limita el uso de tipos anónimos a variables locales.

Los tipos anónimos proporcionan compatibilidad crítica para 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 tipo anónimo serán propiedades clave, que se indican escribiendo la palabra clave Key delante del nombre de propiedad.

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

    Para obtener más información sobre las propiedades de clave, consulte Key.

  • Al igual que los tipos con nombre, las listas de inicializadores para las definiciones de tipos anónimos deben 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 los tipos de datos de las propiedades se toman de la declaración de instancia y los incluye el compilador en la definición. Las propiedades no se denominan y se definen de antemano, como ocurriría con un tipo con nombre. Sus tipos se infieren. No se pueden especificar los tipos de datos de las propiedades mediante una As cláusula .

  • Los tipos anónimos también pueden establecer los nombres y valores de sus propiedades de otras maneras. Por ejemplo, una propiedad de tipo anónimo puede tomar tanto el nombre como el valor de una variable, o el nombre y el 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 en tipos anónimos, vea How to: Infer Property Names and Types in Anonymous Type Declarations.

Consulte también