Inicializadores de objeto: Tipos con nombre y anónimos (Visual Basic)Object Initializers: Named and Anonymous Types (Visual Basic)

Los inicializadores de objeto permiten especificar propiedades para un objeto complejo mediante el uso de una sola expresión.Object initializers enable you to specify properties for a complex object by using a single expression. Se pueden usar para crear instancias de tipos con nombre y de tipos anónimos.They can be used to create instances of named types and of anonymous types.

DeclaracionesDeclarations

Las declaraciones de instancias de tipos con nombre y anónimos pueden ser prácticamente idénticas, pero sus efectos no son los mismos.Declarations of instances of named and anonymous types can look almost identical, but their effects are not the same. Cada categoría tiene capacidades y restricciones propias.Each category has abilities and restrictions of its own. 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 objeto.The following example shows a convenient way to declare and initialize an instance of a named class, Customer, by using an object initializer list. Observe que el nombre de la clase se especifica después de la palabra clave New.Notice that the name of the class is specified after the keyword New.

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

Un tipo anónimo no tiene ningún nombre utilizable.An anonymous type has no usable name. Por lo tanto, una creación de instancias de un tipo anónimo no puede incluir un nombre de clase.Therefore an instantiation of an anonymous type cannot include a class name.

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

Los requisitos y los resultados de las dos declaraciones no son los mismos.The requirements and results of the two declarations are not the same. Por namedCust, ya debe existir una clase Customer que tenga una propiedad Name y la declaración creará una instancia de esa clase.For namedCust, a Customer class that has a Name property must already exist, and the declaration creates an instance of that class. Por anonymousCust, el compilador define una nueva clase que tiene una propiedad, una cadena llamada Namey crea una nueva instancia de esa clase.For anonymousCust, the compiler defines a new class that has one property, a string called Name, and creates a new instance of that class.

Tipos con nombreNamed Types

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 en una única instrucción.Object initializers provide a simple way to call the constructor of a type and then set the values of some or all properties in a single statement. El compilador invoca el constructor adecuado para la instrucción: el constructor sin parámetros si no se presentan argumentos, o un constructor con parámetros si se envían uno o más argumentos.The compiler invokes the appropriate constructor for the statement: the parameterless constructor if no arguments are presented, or a parameterized constructor if one or more arguments are sent. Después, las propiedades especificadas se inicializan en el orden en que se presentan en la lista de inicializadores.After that, the specified properties are initialized in the order in which they are presented in the initializer list.

Cada inicialización en la lista de inicializadores consta de la asignación de un valor inicial a un miembro de la clase.Each initialization in the initializer list consists of the assignment of an initial value to a member of the class. Los nombres y los tipos de datos de los miembros se determinan cuando se define la clase.The names and data types of the members are determined when the class is defined. En los ejemplos siguientes, la clase Customer debe existir y debe tener miembros denominados Name y City que pueden aceptar valores de cadena.In the following examples, the Customer class must exist, and must have members named Name and City that can accept string values.

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

Como alternativa, puede obtener el mismo resultado mediante el código siguiente:Alternatively, you can obtain the same result by using the following code:

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 propiedades Name y City mediante una instrucción With.Each of these declarations is equivalent to the following example, which creates a Customer object by using the parameterless constructor, and then specifies initial values for the Name and City properties by using a With statement.

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 le permite enviar un valor para Name, por ejemplo, también puede declarar e inicializar un objeto Customer de las siguientes maneras:If the Customer class contains a parameterized constructor that enables you to send in a value for Name, for example, you can also declare and initialize a Customer object in the following ways:

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.You do not have to initialize all properties, as the following code shows.

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

Sin embargo, la lista de inicialización no puede estar vacía.However, the initialization list cannot be empty. Las propiedades sin inicializar conservan sus valores predeterminados.Uninitialized properties retain their default values.

Inferencia de tipos con tipos con nombreType Inference with Named Types

Puede acortar el código para la declaración de cust1 combinando inicializadores de objeto e inferencia de tipo local.You can shorten the code for the declaration of cust1 by combining object initializers and local type inference. Esto le permite omitir la cláusula As en la declaración de la variable.This enables you to omit the As clause in the variable declaration. El tipo de datos de la variable se deduce del tipo del objeto creado por la asignación.The data type of the variable is inferred from the type of the object that is created by the assignment. En el ejemplo siguiente, el tipo de cust6 es Customer.In the following example, the type of cust6 is Customer.

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

Comentarios acerca de los tipos con nombreRemarks About Named Types

  • No se puede inicializar un miembro de clase más de una vez en la lista de inicializadores de objeto.A class member cannot be initialized more than one time in the object initializer list. La declaración de cust7 produce un error.The declaration of cust7 causes an 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.A member can be used to initialize itself or another field. Si se tiene acceso a un miembro antes de que se haya inicializado, como en la siguiente declaración de cust8, se usará el valor predeterminado.If a member is accessed before it has been initialized, as in the following declaration for cust8, the default value will be used. Recuerde que cuando se procesa una declaración que usa un inicializador de objeto, lo primero que ocurre es que se invoca el constructor adecuado.Remember that when a declaration that uses an object initializer is processed, the first thing that happens is that the appropriate constructor is invoked. Después, se inicializan los campos individuales en la lista de inicializadores.After that, the individual fields in the initializer list are initialized. En los ejemplos siguientes, se asigna el valor predeterminado de Name para cust8y se asigna un valor inicializado en cust9.In the following examples, the default value for Name is assigned for cust8, and an initialized value is assigned in 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 utiliza el constructor con parámetros de cust3 y cust4 para declarar e inicializar cust10 y cust11.The following example uses the parameterized constructor from cust3 and cust4 to declare and initialize cust10 and 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 se pueden anidar.Object initializers can be nested. 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.In the following example, AddressClass is a class that has two properties, City and State, and the Customer class has an Address property that is an instance of 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.The initialization list cannot be empty.

  • La instancia que se está inicializando no puede ser de tipo Object.The instance being initialized cannot be of type Object.

  • Los miembros de clase que se van a inicializar no pueden ser miembros compartidos, miembros de solo lectura, constantes o llamadas a métodos.Class members being initialized cannot be shared members, read-only members, constants, or method calls.

  • Los miembros de clase que se van a inicializar no se pueden indizar ni calificar.Class members being initialized cannot be indexed or qualified. En los siguientes ejemplos se producen errores del compilador:The following examples raise compiler errors:

    '' Not valid.

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

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

Tipos anónimosAnonymous Types

Los tipos anónimos usan inicializadores de objeto para crear instancias de nuevos tipos que no se definen explícitamente ni se denominan.Anonymous types use object initializers to create instances of new types that you do not explicitly define and name. En su lugar, el compilador genera un tipo de acuerdo con las propiedades que se designan en la lista de inicializadores de objeto.Instead, the compiler generates a type according to the properties you designate in the object initializer list. Dado que no se especifica el nombre del tipo, se hace referencia a él como un tipo anónimo.Because the name of the type is not specified, it is referred to as an anonymous type. Por ejemplo, compare la siguiente declaración con la anterior para cust6.For example, compare the following declaration to the earlier one for cust6.

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

La única diferencia sintácticamente es que no se especifica ningún nombre después de New para el tipo de datos.The only difference syntactically is that no name is specified after New for the data type. Sin embargo, lo que sucede es bastante diferente.However, what happens is quite different. El compilador define un nuevo tipo anónimo que tiene dos propiedades, Name y City, y crea una instancia de ella con los valores especificados.The compiler defines a new anonymous type that has two properties, Name and City, and creates an instance of it with the specified values. La inferencia de tipos determina los tipos de Name y City en el ejemplo que son cadenas.Type inference determines the types of Name and City in the example to be strings.

Precaución

El compilador genera el nombre del tipo anónimo y puede variar de la compilación a la compilación.The name of the anonymous type is generated by the compiler, and may vary from compilation to compilation. El código no debe utilizar ni basarse en el nombre de un tipo anónimo.Your code should not use or rely on the name of an anonymous type.

Dado que el nombre del tipo no está disponible, no se puede usar una cláusula As para declarar cust13.Because the name of the type is not available, you cannot use an As clause to declare cust13. Se debe inferir su tipo.Its type must be inferred. Sin usar el enlace en tiempo de ejecución, esto limita el uso de tipos anónimos a variables locales.Without using late binding, this limits the use of anonymous types to local variables.

Los tipos anónimos proporcionan compatibilidad crítica para las consultas LINQ.Anonymous types provide critical support for LINQ queries. Para obtener más información sobre el uso de tipos anónimos en las consultas, vea tipos anónimos e Introducción a LINQ en Visual Basic.For more information about the use of anonymous types in queries, see Anonymous Types and Introduction to LINQ in Visual Basic.

Comentarios acerca de los tipos anónimosRemarks About Anonymous Types

  • Normalmente, todas o la mayoría de las propiedades de una declaración de tipo anónimo serán propiedades de clave, que se indican escribiendo la palabra clave Key delante del nombre de la propiedad.Typically, all or most of the properties in an anonymous type declaration will be key properties, which are indicated by typing the keyword Key in front of the property name.

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

    Para obtener más información acerca de las propiedades de clave, consulte key.For more information about key properties, see Key.

  • Al igual que los tipos con nombre, las listas de inicializadores para definiciones de tipos anónimos deben declarar al menos una propiedad.Like named types, initializer lists for anonymous type definitions must declare at least one property.

    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.When an instance of an anonymous type is declared, the compiler generates a matching anonymous type definition. Los nombres y los tipos de datos de las propiedades se toman de la declaración de instancia y se incluyen en el compilador en la definición.The names and data types of the properties are taken from the instance declaration, and are included by the compiler in the definition. Las propiedades no tienen nombre y se definen de antemano, como serían para un tipo con nombre.The properties are not named and defined in advance, as they would be for a named type. Se deducen sus tipos.Their types are inferred. No se pueden especificar los tipos de datos de las propiedades mediante el uso de una cláusula As.You cannot specify the data types of the properties by using an As clause.

  • Los tipos anónimos también pueden establecer los nombres y valores de sus propiedades de varias maneras.Anonymous types can also establish the names and values of their properties in several other ways. Por ejemplo, una propiedad de tipo anónimo puede tomar el nombre y el valor de una variable, o el nombre y el valor de una propiedad de otro objeto.For example, an anonymous type property can take both the name and the value of a variable, or the name and value of a property of another object.

    ' 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 Cómo: inferir nombres y tipos de propiedades en declaraciones de tipos anónimos.For more information about the options for defining properties in anonymous types, see How to: Infer Property Names and Types in Anonymous Type Declarations.

Vea tambiénSee also