Sistema de tipos comunesCommon Type System

Common Type System define cómo se declaran, usan y administran los tipos en Common Language Runtime. Es también una parte importante de la compatibilidad en tiempo de ejecución con la integración entre lenguajes.The common type system defines how types are declared, used, and managed in the common language runtime, and is also an important part of the runtime's support for cross-language integration. El sistema de tipos común realiza las funciones siguientes:The common type system performs the following functions:

  • Establece un marco de trabajo que ayuda a permitir la integración entre lenguajes, la seguridad de tipos y la ejecución de código de alto rendimiento.Establishes a framework that helps enable cross-language integration, type safety, and high-performance code execution.

  • Proporciona un modelo orientado a objetos que admite la implementación completa de muchos lenguajes de programación.Provides an object-oriented model that supports the complete implementation of many programming languages.

  • Define reglas que deben seguir los lenguajes, lo que ayuda a garantizar que los objetos escritos en distintos lenguajes puedan interactuar unos con otros.Defines rules that languages must follow, which helps ensure that objects written in different languages can interact with each other.

  • Proporciona una biblioteca que contiene los tipos de datos primitivos (como Boolean, Byte, Char, Int32 y UInt64) que se emplean en el desarrollo de aplicaciones.Provides a library that contains the primitive data types (such as Boolean, Byte, Char, Int32, and UInt64) used in application development.

Este tema contiene las siguientes secciones:This topic contains the following sections:

Tipos de .NETTypes in .NET

Todos los tipos de .NET son tipos de valor o tipos de referencia.All types in .NET are either value types or reference types.

Los tipos de valor son tipos de datos cuyos objetos se representan mediante el valor real del objeto.Value types are data types whose objects are represented by the object's actual value. Si se asigna una instancia de un tipo de valor a una variable, esa variable obtiene una copia reciente del valor.If an instance of a value type is assigned to a variable, that variable is given a fresh copy of the value.

Los tipos de referencia son tipos de datos cuyos objetos se representan mediante una referencia (similar a un puntero) al valor real del objeto.Reference types are data types whose objects are represented by a reference (similar to a pointer) to the object's actual value. Si se asigna un tipo de referencia a una variable, esa variable hace referencia (o apunta) al valor original.If a reference type is assigned to a variable, that variable references (points to) the original value. No se realiza ninguna copia.No copy is made.

Common Type System en .NET admite las cinco categorías de tipos siguientes:The common type system in .NET supports the following five categories of types:

ClasesClasses

Una clase es un tipo de referencia que se puede derivar directamente de otra clase y que se deriva implícitamente de System.Object.A class is a reference type that can be derived directly from another class and that is derived implicitly from System.Object. La clase define las operaciones que un objeto (que es una instancia de la clase) puede realizar (métodos, eventos o propiedades) y los datos que el objeto contiene (campos).The class defines the operations that an object (which is an instance of the class) can perform (methods, events, or properties) and the data that the object contains (fields). Aunque una clase suele incluir una definición y una implementación (a diferencia, por ejemplo, de las interfaces, que solo contienen una definición sin implementación), puede tener uno o varios miembros sin implementación.Although a class generally includes both definition and implementation (unlike interfaces, for example, which contain only definition without implementation), it can have one or more members that have no implementation.

En la tabla siguiente se describen algunas de las características que una clase puede tener.The following table describes some of the characteristics that a class may have. Cada lenguaje compatible con el motor en tiempo de ejecución proporciona una forma de indicar que una clase o un miembro de clase tiene una o varias de estas características.Each language that supports the runtime provides a way to indicate that a class or class member has one or more of these characteristics. En cambio, puede que no estén disponibles todas estas características en los lenguajes de programación orientados a .NET.However, individual programming languages that target .NET may not make all these characteristics available.

CaracterísticaCharacteristic DESCRIPCIÓNDescription
sealedsealed Especifica que no se puede derivar otra clase de este tipo.Specifies that another class cannot be derived from this type.
implementaimplements Indica que la clase utiliza una o varias interfaces proporcionando implementaciones de miembros de la interfaz.Indicates that the class uses one or more interfaces by providing implementations of interface members.
abstractabstract Indica que no se pueden crear instancias de la clase.Indicates that the class cannot be instantiated. Para utilizarla se debe derivar de ella otra clase.To use it, you must derive another class from it.
heredainherits Indica que las instancias de la clase se pueden utilizar en cualquier lugar en que se especifique la clase base.Indicates that instances of the class can be used anywhere the base class is specified. Una clase derivada que hereda de una clase base puede usar la implementación de cualquier miembro público proporcionado por la clase base o la clase derivada puede invalidar la implementación de los miembros públicos con su propia implementación.A derived class that inherits from a base class can use the implementation of any public members provided by the base class, or the derived class can override the implementation of the public members with its own implementation.
exported o not exportedexported or not exported Indica si una clase está visible fuera del ensamblado en el que se define.Indicates whether a class is visible outside the assembly in which it is defined. Esta característica se aplica únicamente a las clases de nivel superior y no a las clases anidadas.This characteristic applies only to top-level classes and not to nested classes.

Nota

Una clase también puede estar anidada en una estructura o clase primaria.A class can also be nested in a parent class or structure. Las clases anidadas tienen también características de miembro.Nested classes also have member characteristics. Para obtener más información, consulte Tipos anidados.For more information, see Nested Types.

Los miembros de clase que no tienen implementación son miembros abstractos.Class members that have no implementation are abstract members. Una clase que tiene uno o varios miembros abstractos es abstracta y no se pueden crear nuevas instancias de ella.A class that has one or more abstract members is itself abstract; new instances of it cannot be created. Algunos lenguajes destinados al motor en tiempo de ejecución permiten marcar una clase como abstracta incluso aunque no tenga ningún miembro abstracto.Some languages that target the runtime let you mark a class as abstract even if none of its members are abstract. Se puede usar una clase abstracta cuando se desea encapsular un conjunto básico de funcionalidad que las clases derivadas pueden heredar o invalidar según corresponda.You can use an abstract class when you want to encapsulate a basic set of functionality that derived classes can inherit or override when appropriate. Las clases que no son abstractas se conocen como clases concretas.Classes that are not abstract are referred to as concrete classes.

Una clase puede implementar cualquier número de interfaces pero puede heredar solo de una clase base además de la clase System.Object, de la que todas las clases heredan implícitamente.A class can implement any number of interfaces, but it can inherit from only one base class in addition to System.Object, from which all classes inherit implicitly. Todas las clases deben tener al menos un constructor, que inicializa nuevas instancias de la clase.All classes must have at least one constructor, which initializes new instances of the class. Si no se define explícitamente un constructor, la mayoría de los compiladores proporcionarán automáticamente un constructor sin parámetros.If you do not explicitly define a constructor, most compilers will automatically provide a parameterless constructor.

EstructurasStructures

Una estructura es un tipo de valor que se deriva implícitamente de System.ValueType, que a su vez se deriva de System.Object.A structure is a value type that derives implicitly from System.ValueType, which in turn is derived from System.Object. Una estructura es muy útil para representar valores cuyos requisitos de memoria son reducidos y para pasar valores como parámetros por valor a los métodos que tienen parámetros fuertemente tipados.A structure is very useful for representing values whose memory requirements are small, and for passing values as by-value parameters to methods that have strongly typed parameters. En .NET, todos los tipos de datos primitivos (Boolean, Byte, Char, DateTime, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32 y UInt64) se definen como estructuras.In .NET, all primitive data types (Boolean, Byte, Char, DateTime, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32, and UInt64) are defined as structures.

Al igual que las clases, las estructuras definen datos (los campos de la estructura) y las operaciones que se pueden realizar con esos datos (los métodos de la estructura).Like classes, structures define both data (the fields of the structure) and the operations that can be performed on that data (the methods of the structure). Esto significa que se puede llamar a los métodos en las estructuras, incluso a los métodos virtuales definidos en las clases System.Object y System.ValueType, y a cualquier método definido en el propio tipo de valor.This means that you can call methods on structures, including the virtual methods defined on the System.Object and System.ValueType classes, and any methods defined on the value type itself. Es decir, las estructuras pueden tener campos, propiedades y eventos, así como métodos estáticos y no estáticos.In other words, structures can have fields, properties, and events, as well as static and nonstatic methods. Se pueden crear instancias de las estructuras, pasarlas como parámetros, almacenarlas como variables locales o almacenarlas en un campo de otro tipo de valor o tipo de referencia.You can create instances of structures, pass them as parameters, store them as local variables, or store them in a field of another value type or reference type. Las estructuras también pueden implementar interfaces.Structures can also implement interfaces.

Los tipos de valor también difieren de las clases en varios aspectos.Value types also differ from classes in several respects. En primer lugar, aunque heredan implícitamente de System.ValueType, no pueden heredar directamente de ningún tipo.First, although they implicitly inherit from System.ValueType, they cannot directly inherit from any type. De manera similar, todos los tipos de valor están sellados, lo que quiere decir que de ellos no se puede derivar ningún otro tipo.Similarly, all value types are sealed, which means that no other type can be derived from them. Tampoco necesitan constructores.They also do not require constructors.

Para cada tipo de valor, Common Language Runtime proporciona un tipo correspondiente al que se ha aplicado la conversión boxing, que es una clase que tiene el mismo estado y comportamiento que el tipo de valor.For each value type, the common language runtime supplies a corresponding boxed type, which is a class that has the same state and behavior as the value type. A una instancia de un tipo de valor se le aplica la conversión boxing cuando se pasa a un método que acepta un parámetro de tipo System.Object.An instance of a value type is boxed when it is passed to a method that accepts a parameter of type System.Object. Se le aplica la conversión unboxing (es decir, se vuelve a convertir la instancia de una clase en una instancia de un tipo de valor) cuando se devuelve el control de una llamada a un método que acepta un tipo de valor como parámetro por referencia.It is unboxed (that is, converted from an instance of a class back to an instance of a value type) when control returns from a method call that accepts a value type as a by-reference parameter. En el caso de algunos lenguajes, se debe usar una sintaxis especial cuando se necesita el tipo al que se haya aplicado la conversión boxing, mientras que otros emplean el tipo automáticamente cuando es necesario.Some languages require that you use special syntax when the boxed type is required; others automatically use the boxed type when it is needed. Cuando se define un tipo de valor, se definen los dos tipos: al que se ha aplicado la conversión boxing y al que se ha aplicado la conversión unboxing.When you define a value type, you are defining both the boxed and the unboxed type.

EnumeracionesEnumerations

Una enumeración (enum) es un tipo de valor que hereda directamente de System.Enum y proporciona nombres alternativos para los valores de un tipo primitivo subyacente.An enumeration (enum) is a value type that inherits directly from System.Enum and that supplies alternate names for the values of an underlying primitive type. Un tipo de enumeración tiene un nombre, un tipo subyacente que debe ser uno de los tipos de enteros con o sin signo integrados (como Byte, Int32 o UInt64) y un conjunto de campos.An enumeration type has a name, an underlying type that must be one of the built-in signed or unsigned integer types (such as Byte, Int32, or UInt64), and a set of fields. Los campos son campos literales estáticos, cada uno de los cuales representa una constante.The fields are static literal fields, each of which represents a constant. El mismo valor se puede asignar a varios campos.The same value can be assigned to multiple fields. Cuando esto sucede, se debe marcar uno de los valores como valor de enumeración primario para la reflexión y la conversión de cadenas.When this occurs, you must mark one of the values as the primary enumeration value for reflection and string conversion.

Se puede asignar un valor del tipo subyacente a una enumeración y viceversa, y no es necesario que el motor en tiempo de ejecución realice una conversión.You can assign a value of the underlying type to an enumeration and vice versa (no cast is required by the runtime). Se puede crear una instancia de una enumeración y llamar a los métodos de System.Enum, además de llamar a cualquier método definido en el tipo subyacente de la enumeración.You can create an instance of an enumeration and call the methods of System.Enum, as well as any methods defined on the enumeration's underlying type. Sin embargo, algunos lenguajes no permiten pasar una enumeración como parámetro cuando se necesita una instancia del tipo subyacente (o viceversa).However, some languages might not let you pass an enumeration as a parameter when an instance of the underlying type is required (or vice versa).

A las enumeraciones se les aplican las restricciones siguientes:The following additional restrictions apply to enumerations:

  • No pueden definir sus propios métodos.They cannot define their own methods.

  • No pueden implementar interfaces.They cannot implement interfaces.

  • No pueden definir propiedades ni eventos.They cannot define properties or events.

  • No pueden ser genéricas, a menos que sean genéricas solo porque están anidadas dentro de un tipo genérico.They cannot be generic, unless they are generic only because they are nested within a generic type. Es decir, una enumeración no puede tener parámetros de tipo propios.That is, an enumeration cannot have type parameters of its own.

    Nota

    Los tipos anidados (incluidas las enumeraciones) creados con Visual Basic, C# y C++ incluyen los parámetros de tipo de todos los tipos genéricos envolventes, por lo que son genéricos aunque no tengan parámetros de tipo propios.Nested types (including enumerations) created with Visual Basic, C#, and C++ include the type parameters of all enclosing generic types, and are therefore generic even if they do not have type parameters of their own. Para obtener más información, vea la sección "Tipos anidados" en el tema de referencia del método Type.MakeGenericType.For more information, see "Nested Types" in the Type.MakeGenericType reference topic.

El atributo FlagsAttribute indica una clase especial de enumeración denominada campo de bits.The FlagsAttribute attribute denotes a special kind of enumeration called a bit field. El motor en tiempo de ejecución no distingue entre enumeraciones tradicionales y campos de bits, pero el lenguaje podría hacerlo.The runtime itself does not distinguish between traditional enumerations and bit fields, but your language might do so. Cuando se hace esta distinción, se pueden utilizar operadores bit a bit en estos campos de bits, para generar valores sin nombre, pero no en las enumeraciones.When this distinction is made, bitwise operators can be used on bit fields, but not on enumerations, to generate unnamed values. Normalmente, las enumeraciones se utilizan para listas de elementos únicos, como los días de la semana, los nombres de países o regiones, etc.Enumerations are generally used for lists of unique elements, such as days of the week, country or region names, and so on. Los campos de bits se utilizan, en general, para listas de calidades o cantidades que pueden producirse en combinaciones, como Red And Big And Fast.Bit fields are generally used for lists of qualities or quantities that might occur in combination, such as Red And Big And Fast.

En el ejemplo siguiente se muestra cómo utilizar los campos de bits y las enumeraciones tradicionales.The following example shows how to use both bit fields and traditional enumerations.

using System;
using System.Collections.Generic;

// A traditional enumeration of some root vegetables.
public enum SomeRootVegetables
{
    HorseRadish,
    Radish,
    Turnip
}

// A bit field or flag enumeration of harvesting seasons.
[Flags]
public enum Seasons
{
    None = 0,
    Summer = 1,
    Autumn = 2,
    Winter = 4,
    Spring = 8,
    All = Summer | Autumn | Winter | Spring
}

public class Example
{
   public static void Main()
   {
       // Hash table of when vegetables are available.
       Dictionary<SomeRootVegetables, Seasons> AvailableIn = new Dictionary<SomeRootVegetables, Seasons>();

       AvailableIn[SomeRootVegetables.HorseRadish] = Seasons.All;
       AvailableIn[SomeRootVegetables.Radish] = Seasons.Spring;
       AvailableIn[SomeRootVegetables.Turnip] = Seasons.Spring | 
            Seasons.Autumn;

       // Array of the seasons, using the enumeration.
       Seasons[] theSeasons = new Seasons[] { Seasons.Summer, Seasons.Autumn, 
            Seasons.Winter, Seasons.Spring };

       // Print information of what vegetables are available each season.
       foreach (Seasons season in theSeasons)
       {
          Console.Write(String.Format(
              "The following root vegetables are harvested in {0}:\n", 
              season.ToString("G")));
          foreach (KeyValuePair<SomeRootVegetables, Seasons> item in AvailableIn)
          {
             // A bitwise comparison.
             if (((Seasons)item.Value & season) > 0)
                 Console.Write(String.Format("  {0:G}\n", 
                      (SomeRootVegetables)item.Key));
          }
       }
   }
}
// The example displays the following output:
//    The following root vegetables are harvested in Summer:
//      HorseRadish
//    The following root vegetables are harvested in Autumn:
//      Turnip
//      HorseRadish
//    The following root vegetables are harvested in Winter:
//      HorseRadish
//    The following root vegetables are harvested in Spring:
//      Turnip
//      Radish
//      HorseRadish
Imports System.Collections.Generic

' A traditional enumeration of some root vegetables.
Public Enum SomeRootVegetables
   HorseRadish
   Radish
   Turnip
End Enum 

' A bit field or flag enumeration of harvesting seasons.
<Flags()> Public Enum Seasons
   None = 0
   Summer = 1
   Autumn = 2
   Winter = 4
   Spring = 8
   All = Summer Or Autumn Or Winter Or Spring
End Enum 

' Entry point.
Public Class Example
   Public Shared Sub Main()
      ' Hash table of when vegetables are available.
      Dim AvailableIn As New Dictionary(Of SomeRootVegetables, Seasons)()
        
      AvailableIn(SomeRootVegetables.HorseRadish) = Seasons.All
      AvailableIn(SomeRootVegetables.Radish) = Seasons.Spring
      AvailableIn(SomeRootVegetables.Turnip) = Seasons.Spring Or _
                                               Seasons.Autumn
        
      ' Array of the seasons, using the enumeration.
      Dim theSeasons() As Seasons = {Seasons.Summer, Seasons.Autumn, _
                                     Seasons.Winter, Seasons.Spring}
        
      ' Print information of what vegetables are available each season.
      For Each season As Seasons In theSeasons
         Console.WriteLine(String.Format( _
              "The following root vegetables are harvested in {0}:", _
              season.ToString("G")))
         For Each item As KeyValuePair(Of SomeRootVegetables, Seasons) In AvailableIn
            ' A bitwise comparison.
            If(CType(item.Value, Seasons) And season) > 0 Then
               Console.WriteLine("  " + _
                     CType(item.Key, SomeRootVegetables).ToString("G"))
            End If
         Next
      Next
   End Sub 
End Class 
' The example displays the following output:
'    The following root vegetables are harvested in Summer:
'      HorseRadish
'    The following root vegetables are harvested in Autumn:
'      Turnip
'      HorseRadish
'    The following root vegetables are harvested in Winter:
'      HorseRadish
'    The following root vegetables are harvested in Spring:
'      Turnip
'      Radish
'      HorseRadish

InterfacesInterfaces

Una interfaz define un contrato que especifica una relación de lo que se puede hacer o una relación de lo que se tiene.An interface defines a contract that specifies a "can do" relationship or a "has a" relationship. Las interfaces se utilizan a menudo para implementar una funcionalidad, como comparar y ordenar (interfaces IComparable e IComparable<T>), comprobar la igualdad (interfaz IEquatable<T>) o enumerar los elementos de una colección (interfaces IEnumerable e IEnumerable<T>).Interfaces are often used to implement functionality, such as comparing and sorting (the IComparable and IComparable<T> interfaces), testing for equality (the IEquatable<T> interface), or enumerating items in a collection (the IEnumerable and IEnumerable<T> interfaces). Las interfaces pueden tener propiedades, métodos y eventos, que son todos miembros abstractos; es decir, aunque la interfaz define los miembros y sus firmas, deja que el tipo encargado de implementar la interfaz defina la funcionalidad de cada miembro de la interfaz.Interfaces can have properties, methods, and events, all of which are abstract members; that is, although the interface defines the members and their signatures, it leaves it to the type that implements the interface to define the functionality of each interface member. Esto significa que cualquier clase o estructura que implemente una interfaz debe proporcionar definiciones de los miembros abstractos declarados en la interfaz.This means that any class or structure that implements an interface must supply definitions for the abstract members declared in the interface. Una interfaz puede necesitar que cualquier clase o estructura que implemente una interfaz implemente también otras interfaces.An interface can require any implementing class or structure to also implement one or more other interfaces.

A las interfaces se les aplican las restricciones siguientes:The following restrictions apply to interfaces:

  • Una interfaz se puede declarar con cualquier tipo de accesibilidad, pero los miembros de la interfaz deben tener todos accesibilidad pública.An interface can be declared with any accessibility, but interface members must all have public accessibility.

  • Las interfaces no pueden definir constructoresInterfaces cannot define constructors.

  • Las interfaces no pueden definir campos.Interfaces cannot define fields.

  • Las interfaces solo pueden definir miembros de instancia.Interfaces can define only instance members. No pueden definir miembros estáticos.They cannot define static members.

Cada lenguaje debe proporcionar reglas para asignar una implementación a la interfaz que necesita el miembro, ya que varias interfaces pueden declarar un miembro con la misma firma y esos miembros pueden tener implementaciones independientes.Each language must provide rules for mapping an implementation to the interface that requires the member, because more than one interface can declare a member with the same signature, and these members can have separate implementations.

DelegadosDelegates

Los delegados son tipos de referencia con una finalidad similar a la de los punteros a función de C++.Delegates are reference types that serve a purpose similar to that of function pointers in C++. Se usan para los controladores de eventos y las funciones de devolución de llamada en .NET.They are used for event handlers and callback functions in .NET. A diferencia de los punteros a función, los delegados son seguros, se pueden comprobar y proporcionan seguridad de tipos.Unlike function pointers, delegates are secure, verifiable, and type safe. Un tipo de delegado puede representar cualquier método de instancia o método estático que tenga una firma compatible.A delegate type can represent any instance method or static method that has a compatible signature.

Un parámetro de un delegado es compatible con el parámetro correspondiente de un método si el tipo del parámetro del delegado es más restrictivo que el del método, porque así se garantiza que el argumento que se pase al delegado también se podrá pasar de forma segura al método.A parameter of a delegate is compatible with the corresponding parameter of a method if the type of the delegate parameter is more restrictive than the type of the method parameter, because this guarantees that an argument passed to the delegate can be passed safely to the method.

De forma similar, el tipo de valor devuelto de un delegado es compatible con el tipo de valor devuelto de un método si el del método es más restrictivo que el del delegado, porque así se garantiza que el tipo de valor devuelto por el método se puede convertir con seguridad al tipo de valor devuelto del delegado.Similarly, the return type of a delegate is compatible with the return type of a method if the return type of the method is more restrictive than the return type of the delegate, because this guarantees that the return value of the method can be cast safely to the return type of the delegate.

Por ejemplo, un delegado que tiene un parámetro de tipo IEnumerable y un tipo de valor devuelto Object puede representar un método que tiene un parámetro de tipo Object y un valor devuelto de tipo IEnumerable.For example, a delegate that has a parameter of type IEnumerable and a return type of Object can represent a method that has a parameter of type Object and a return value of type IEnumerable. Para obtener más información y un código de ejemplo, vea Delegate.CreateDelegate(Type, Object, MethodInfo).For more information and example code, see Delegate.CreateDelegate(Type, Object, MethodInfo).

Se dice que un delegado está enlazado al método que representa.A delegate is said to be bound to the method it represents. Además de estar enlazado al método, un delegado puede estar enlazado a un objeto.In addition to being bound to the method, a delegate can be bound to an object. El objeto representa el primer parámetro del método y se pasa al método cada vez que se invoca el delegado.The object represents the first parameter of the method, and is passed to the method every time the delegate is invoked. Si el método es un método de instancia, el objeto enlazado se pasa como el parámetro this implícito (Me en Visual Basic); si el método es estático, el objeto se pasa como primer parámetro formal del método y la firma del delegado debe coincidir con los parámetros restantes.If the method is an instance method, the bound object is passed as the implicit this parameter (Me in Visual Basic); if the method is static, the object is passed as the first formal parameter of the method, and the delegate signature must match the remaining parameters. Para obtener más información y un código de ejemplo, vea System.Delegate.For more information and example code, see System.Delegate.

Todos los delegados heredan de System.MulticastDelegate, que hereda de System.Delegate.All delegates inherit from System.MulticastDelegate, which inherits from System.Delegate. Los lenguajes C#, Visual Basic y C++ no permiten que se herede de estos tipos.The C#, Visual Basic, and C++ languages do not allow inheritance from these types. En su lugar, proporcionan palabras clave para declarar los delegados.Instead, they provide keywords for declaring delegates.

Dado que los delegados heredan de MulticastDelegate, un delegado tiene una lista de invocación, que es una lista de métodos que representa el delegado y que se ejecutan cuando se llama al delegado.Because delegates inherit from MulticastDelegate, a delegate has an invocation list, which is a list of methods that the delegate represents and that are executed when the delegate is invoked. Todos los métodos de la lista reciben los argumentos proporcionados cuando se invoca al delegado.All methods in the list receive the arguments supplied when the delegate is invoked.

Nota

El valor devuelto no se define para los delegados que tienen más de un método en su lista de invocación, aunque el delegado tenga un tipo de valor devuelto.The return value is not defined for a delegate that has more than one method in its invocation list, even if the delegate has a return type.

En muchos casos, como en el de los métodos de devolución de llamada, un delegado solo representa un método y las únicas acciones que se deben llevar a cabo son la creación y la invocación del delegado.In many cases, such as with callback methods, a delegate represents only one method, and the only actions you have to take are creating the delegate and invoking it.

Por lo que se refiere a los delegados que representan varios métodos, .NET proporciona métodos de las clases de delegado Delegate y MulticastDelegate para operaciones tales como agregar un método a una lista de invocación del delegado (el método Delegate.Combine), quitar un método (el método Delegate.Remove) y obtener la lista de invocación (el método Delegate.GetInvocationList).For delegates that represent multiple methods, .NET provides methods of the Delegate and MulticastDelegate delegate classes to support operations such as adding a method to a delegate's invocation list (the Delegate.Combine method), removing a method (the Delegate.Remove method), and getting the invocation list (the Delegate.GetInvocationList method).

Nota

No es preciso usar estos métodos para los delegados de controladores de eventos en C#, C++ ni Visual Basic, ya que estos lenguajes proporcionan sintaxis para agregar y quitar controladores de eventos.It is not necessary to use these methods for event-handler delegates in C#, C++, and Visual Basic, because these languages provide syntax for adding and removing event handlers.

Definiciones de tiposType Definitions

Una definición de tipo incluye lo siguiente:A type definition includes the following:

  • Los atributos definidos en el tipo.Any attributes defined on the type.

  • La accesibilidad del tipo (visibilidad).The type's accessibility (visibility).

  • El nombre del tipo.The type's name.

  • El tipo base del tipo.The type's base type.

  • Las interfaces que implementa el tipo.Any interfaces implemented by the type.

  • Las definiciones de todos los miembros del tipoDefinitions for each of the type's members.

AtributosAttributes

Los atributos proporcionan metadatos adicionales definidos por el usuario .Attributes provide additional user-defined metadata. Normalmente, se emplean para almacenar información adicional sobre un tipo en su ensamblado o para modificar el comportamiento de un miembro de tipo en tiempo de diseño o en tiempo de ejecución.Most commonly, they are used to store additional information about a type in its assembly, or to modify the behavior of a type member in either the design-time or run-time environment.

Los atributos son clases que heredan de System.Attribute.Attributes are themselves classes that inherit from System.Attribute. Los lenguajes que admiten el uso de atributos tienen su propia sintaxis para aplicar atributos a un elemento del lenguaje.Languages that support the use of attributes each have their own syntax for applying attributes to a language element. Los atributos se pueden aplicar a casi cualquier elemento del lenguaje; los elementos específicos a los que se puede aplicar un atributo los define la clase AttributeUsageAttribute aplicada a esa clase de atributos.Attributes can be applied to almost any language element; the specific elements to which an attribute can be applied are defined by the AttributeUsageAttribute that is applied to that attribute class.

Accesibilidad a tiposType Accessibility

Todos los tipos tienen un modificador que rige su accesibilidad desde otros tipos.All types have a modifier that governs their accessibility from other types. En la tabla siguiente se describen las accesibilidades a tipos que admite el motor en tiempo de ejecución.The following table describes the type accessibilities supported by the runtime.

AccesibilidadAccessibility DESCRIPCIÓNDescription
publicpublic Todos los ensamblados pueden tener acceso al tipo.The type is accessible by all assemblies.
ensambladoassembly El tipo sólo es accesible desde su ensamblado.The type is accessible only from within its assembly.

La accesibilidad de un tipo anidado depende de su dominio de accesibilidad, que viene determinado por la accesibilidad declarada del miembro y el dominio de accesibilidad del tipo contenedor inmediato.The accessibility of a nested type depends on its accessibility domain, which is determined by both the declared accessibility of the member and the accessibility domain of the immediately containing type. Sin embargo, el dominio de accesibilidad de un tipo anidado no puede superar al del tipo contenedor.However, the accessibility domain of a nested type cannot exceed that of the containing type.

El dominio de accesibilidad de un miembro anidado M declarado en un tipo T dentro de un programa P se define de la manera siguiente (teniendo en cuenta que el propio miembro M puede ser un tipo):The accessibility domain of a nested member M declared in a type T within a program P is defined as follows (noting that M might itself be a type):

  • Si la accesibilidad declarada de M es public, el dominio de accesibilidad de M es el dominio de accesibilidad de T.If the declared accessibility of M is public, the accessibility domain of M is the accessibility domain of T.

  • Si la accesibilidad declarada de M es protected internal, el dominio de accesibilidad de M es la intersección del dominio de accesibilidad de T con el texto de programa de P y el texto de programa de cualquier tipo derivado de T declarado fuera de P.If the declared accessibility of M is protected internal, the accessibility domain of M is the intersection of the accessibility domain of T with the program text of P and the program text of any type derived from T declared outside P.

  • Si la accesibilidad declarada de M es protected, el dominio de accesibilidad de M es la intersección del dominio de accesibilidad de T con el texto de programa de T y cualquier tipo derivado de T.If the declared accessibility of M is protected, the accessibility domain of M is the intersection of the accessibility domain of T with the program text of T and any type derived from T.

  • Si la accesibilidad declarada de M es internal, el dominio de accesibilidad de M es la intersección del dominio de accesibilidad de T con el texto de programa de P.If the declared accessibility of M is internal, the accessibility domain of M is the intersection of the accessibility domain of T with the program text of P.

  • Si la accesibilidad declarada de M es private, el dominio de accesibilidad de M es el texto de programa de T.If the declared accessibility of M is private, the accessibility domain of M is the program text of T.

Nombres de tipoType Names

El sistema de tipos común sólo impone dos restricciones en los nombres:The common type system imposes only two restrictions on names:

  • Todos los nombres se codifican como cadenas de caracteres Unicode (de 16 bits).All names are encoded as strings of Unicode (16-bit) characters.

  • Los nombres no pueden tener un valor incrustado (de 16 bits) de 0x0000.Names are not permitted to have an embedded (16-bit) value of 0x0000.

Sin embargo, la mayoría de los lenguajes imponen restricciones adicionales sobre los nombres de tipo.However, most languages impose additional restrictions on type names. Todas las comparaciones se realizan byte a byte, por lo que distinguen entre mayúsculas y minúsculas y son independientes de la configuración regional.All comparisons are done on a byte-by-byte basis, and are therefore case-sensitive and locale-independent.

Aunque un tipo puede hacer referencia a tipos de otros módulos y ensamblados, es preciso que se defina íntegramente en un solo módulo de .NET.Although a type might reference types from other modules and assemblies, a type must be fully defined within one .NET module. (Sin embargo, según la compatibilidad del compilador, se puede dividir en varios archivos de código fuente.) Los nombres de tipo solo tienen que ser únicos dentro de un espacio de nombres.(Depending on compiler support, however, it can be divided into multiple source code files.) Type names need be unique only within a namespace. Para identificar íntegramente un tipo, su nombre debe calificarse con el espacio de nombres que contiene la implementación del tipo.To fully identify a type, the type name must be qualified by the namespace that contains the implementation of the type.

Tipos base e interfacesBase Types and Interfaces

Un tipo puede heredar valores y comportamientos de otro.A type can inherit values and behaviors from another type. El sistema de tipos común no permite que los tipos hereden de más de un tipo base.The common type system does not allow types to inherit from more than one base type.

Un tipo puede implementar cualquier número de interfaces.A type can implement any number of interfaces. Para implementar una interfaz, un tipo debe implementar todos los miembros virtuales de la interfaz.To implement an interface, a type must implement all the virtual members of that interface. Un tipo derivado puede implementar un método virtual, que se puede invocar estática o dinámicamente.A virtual method can be implemented by a derived type and can be invoked either statically or dynamically.

Miembros de tiposType Members

El motor en tiempo de ejecución permite definir miembros de tipos, que especifican el comportamiento y el estado de los tipos.The runtime enables you to define members of your type, which specifies the behavior and state of a type. Los miembros de tipos incluyen lo siguiente:Type members include the following:

CamposFields

Un campo describe y contiene parte del estado del tipo.A field describes and contains part of the type's state. Los campos pueden ser de cualquier tipo que admita el motor en tiempo de ejecución.Fields can be of any type supported by the runtime. Normalmente, los campos son de tipo private o protected, por lo que son accesibles únicamente desde la clase o desde una clase derivada.Most commonly, fields are either private or protected, so that they are accessible only from within the class or from a derived class. Si el valor de un campo se puede modificar desde fuera de su tipo, se suele emplear un descriptor de acceso set de una propiedad.If the value of a field can be modified from outside its type, a property set accessor is typically used. Los campos expuestos públicamente suelen ser de solo lectura y pueden ser de dos tipos:Publicly exposed fields are usually read-only and can be of two types:

  • Constantes, cuyo valor se asigna en tiempo de diseño.Constants, whose value is assigned at design time. Se trata de miembros estáticos de una clase, aunque no se definen mediante la palabra clave static (Shared en Visual Basic).These are static members of a class, although they are not defined using the static (Shared in Visual Basic) keyword.

  • Variables de solo lectura, cuyos valores se pueden asignar en el constructor de clase.Read-only variables, whose values can be assigned in the class constructor.

En el ejemplo siguiente se muestran estos dos usos de los campos de solo lectura.The following example illustrates these two usages of read-only fields.

using System;

public class Constants
{
   public const double Pi = 3.1416;
   public readonly DateTime BirthDate;
   
   public Constants(DateTime birthDate)
   {
      this.BirthDate = birthDate;
   }
}

public class Example
{
   public static void Main()
   {
      Constants con = new Constants(new DateTime(1974, 8, 18));
      Console.Write(Constants.Pi + "\n");
      Console.Write(con.BirthDate.ToString("d") + "\n");
   }
}
// The example displays the following output if run on a system whose current
// culture is en-US:
//    3.1416
//    8/18/1974
Public Class Constants
   Public Const Pi As Double = 3.1416
   Public ReadOnly BirthDate As Date
   
   Public Sub New(birthDate As Date)
      Me.BirthDate = birthDate
   End Sub
End Class

Public Module Example
   Public Sub Main()
      Dim con As New Constants(#8/18/1974#)
      Console.WriteLine(Constants.Pi.ToString())
      Console.WriteLine(con.BirthDate.ToString("d"))
   End Sub
End Module
' The example displays the following output if run on a system whose current
' culture is en-US:
'    3.1416
'    8/18/1974

PropiedadesProperties

Una propiedad identifica un valor o un estado del tipo y define los métodos para obtener o establecer el valor de la propiedad.A property names a value or state of the type and defines methods for getting or setting the property's value. Las propiedades pueden ser tipos primitivos, colecciones de tipos primitivos, tipos definidos por el usuario o colecciones de tipos definidos por el usuario.Properties can be primitive types, collections of primitive types, user-defined types, or collections of user-defined types. Las propiedades se usan a menudo para que la interfaz pública de un tipo se mantenga independiente de la representación real del tipo.Properties are often used to keep the public interface of a type independent from the type's actual representation. De este modo, las propiedades pueden reflejar valores que no están almacenados directamente en la clase (por ejemplo, cuando una propiedad devuelve un valor calculado) o realizar la validación antes de que se asignen valores a campos privados.This enables properties to reflect values that are not directly stored in the class (for example, when a property returns a computed value) or to perform validation before values are assigned to private fields. En el ejemplo siguiente se muestra el último modelo.The following example illustrates the latter pattern.

using System;

public class Person
{
   private int m_Age;
   
   public int Age
   { 
      get { return m_Age; }
      set {
         if (value < 0 || value > 125)
         {
            throw new ArgumentOutOfRangeException("The value of the Age property must be between 0 and 125.");
         }
         else
         {
            m_Age = value;
         }         
      }
   }
}
Public Class Person
   Private m_Age As Integer
   
   Public Property Age As Integer
      Get
         Return m_Age
      End Get
      Set
         If value < 0 Or value > 125 Then
            Throw New ArgumentOutOfRangeException("The value of the Age property must be between 0 and 125.")
         Else
            m_Age = value
         End If
      End Set
   End Property
End Class

Además de incluir la propiedad propiamente dicha, el Lenguaje Intermedio de Microsoft (MSIL) de un tipo que contiene una propiedad de lectura incluye un método get_propertyname y el lenguaje MSIL de un tipo que contiene una propiedad de escritura incluye un método set_propertyname.In addition to including the property itself, the Microsoft intermediate language (MSIL) for a type that contains a readable property includes a get_propertyname method, and the MSIL for a type that contains a writable property includes a set_propertyname method.

MétodosMethods

Un método describe las operaciones que están disponibles en el tipo.A method describes operations that are available on the type. La firma de un método especifica los tipos permitidos de todos sus parámetros y de su valor devuelto.A method's signature specifies the allowable types of all its parameters and of its return value.

Aunque la mayoría de los métodos definen el número exacto de los parámetros necesarios para las llamadas a métodos, algunos admiten un número de parámetros que es variable.Although most methods define the precise number of parameters required for method calls, some methods support a variable number of parameters. El último parámetro declarado de estos métodos se marca con el atributo ParamArrayAttribute.The final declared parameter of these methods is marked with the ParamArrayAttribute attribute. Normalmente, los compiladores de lenguaje proporcionan una palabra clave, como params en C# y ParamArray en Visual Basic, que hace que sea innecesario el uso explícito de ParamArrayAttribute.Language compilers typically provide a keyword, such as params in C# and ParamArray in Visual Basic, that makes explicit use of ParamArrayAttribute unnecessary.

ConstructoresConstructors

Un constructor es un tipo de método especial que crea nuevas instancias de una clase o una estructura.A constructor is a special kind of method that creates new instances of a class or structure. Al igual que cualquier otro método, un constructor puede incluir parámetros; sin embargo, los constructores no tienen ningún valor devuelto (es decir, devuelven void).Like any other method, a constructor can include parameters; however, constructors have no return value (that is, they return void).

Si el código fuente de una clase no define explícitamente un constructor, el compilador incluye un constructor sin parámetros.If the source code for a class does not explicitly define a constructor, the compiler includes a parameterless constructor. Sin embargo, si el código fuente de una clase define solo constructores parametrizados, los compiladores de Visual Basic y C# no generan un constructor sin parámetros.However, if the source code for a class defines only parameterized constructors, the Visual Basic and C# compilers do not generate a parameterless constructor.

Si el código fuente de una estructura define constructores, estos deben tener parámetros; una estructura no puede definir un constructor sin parámetros y los compiladores no generan constructores sin parámetros para las estructuras u otros tipos de valor.If the source code for a structure defines constructors, they must be parameterized; a structure cannot define a parameterless constructor, and compilers do not generate parameterless constructors for structures or other value types. Todos los tipos de valor tienen un constructor sin parámetros implícito.All value types do have an implicit parameterless constructor. Common Language Runtime implementa este constructor, que inicializa todos los campos de la estructura en sus valores predeterminados.This constructor is implemented by the common language runtime and initializes all fields of the structure to their default values.

EventosEvents

Un evento define un incidente al que se puede responder, así como los métodos para suscribirse a un evento, anular la suscripción y generar el evento.An event defines an incident that can be responded to, and defines methods for subscribing to, unsubscribing from, and raising the event. Los eventos se usan con frecuencia para informar a otros tipos de cambios de estado.Events are often used to inform other types of state changes. Para más información, vea Eventos.For more information, see Events.

Tipos anidadosNested Types

Un tipo anidado es un tipo que es un miembro de algún otro tipo.A nested type is a type that is a member of some other type. Los tipos anidados deben estar estrechamente acoplados a su tipo contenedor y no deben ser útiles como tipos de uso general.Nested types should be tightly coupled to their containing type and must not be useful as a general-purpose type. Los tipos anidados son útiles cuando el tipo declarativo utiliza y crea instancias del tipo anidado y el uso de dicho tipo anidado no se expone en miembros públicos.Nested types are useful when the declaring type uses and creates instances of the nested type, and use of the nested type is not exposed in public members.

Los tipos anidados resultan confusos para algunos desarrolladores y no deben estar públicamente visibles a menos que haya una razón de peso.Nested types are confusing to some developers and should not be publicly visible unless there is a compelling reason for visibility. En una biblioteca bien diseñada, los desarrolladores rara vez deberían tener que utilizar tipos anidados para crear instancias de objetos o declarar variables.In a well-designed library, developers should rarely have to use nested types to instantiate objects or declare variables.

Características de los miembros de tiposCharacteristics of Type Members

Common Type System permite que los miembros de tipos tengan diversas características; sin embargo, no es necesario que los lenguajes admitan todas estas características.The common type system allows type members to have a variety of characteristics; however, languages are not required to support all these characteristics. En la siguiente tabla se describen las características de los miembros.The following table describes member characteristics.

CaracterísticaCharacteristic Se puede aplicar aCan apply to DESCRIPCIÓNDescription
abstractabstract Métodos, propiedades y eventosMethods, properties, and events El tipo no proporciona la implementación del método.The type does not supply the method's implementation. Los tipos que heredan o implementan métodos abstractos deben proporcionar una implementación para el método.Types that inherit or implement abstract methods must supply an implementation for the method. La única excepción es que el tipo derivado sea un tipo abstracto.The only exception is when the derived type is itself an abstract type. Todos lo métodos abstractos son virtuales.All abstract methods are virtual.
private, family, assembly, family y assembly, family o assembly, o publicprivate, family, assembly, family and assembly, family or assembly, or public TodasAll Define la accesibilidad del miembro:Defines the accessibility of the member:

privateprivate
Solo es accesible desde el mismo tipo que el miembro o desde un tipo anidado.Accessible only from within the same type as the member, or within a nested type.

familyfamily
Accesible desde el mismo tipo que el miembro y desde tipos derivados que heredan de él.Accessible from within the same type as the member, and from derived types that inherit from it.

ensambladoassembly
Accesible sólo en el ensamblado en que está definido el tipo.Accessible only in the assembly in which the type is defined.

family y assemblyfamily and assembly
Accesible sólo desde los tipos que estén calificados para el acceso de familia y ensamblado.Accessible only from types that qualify for both family and assembly access.

family o assemblyfamily or assembly
Accesible sólo desde los tipos que califican el acceso de familia o ensamblado.Accessible only from types that qualify for either family or assembly access.

publicpublic
Accesible desde cualquier tipo.Accessible from any type.
finalfinal Métodos, propiedades y eventosMethods, properties, and events El método virtual no puede ser reemplazado en un tipo derivado.The virtual method cannot be overridden in a derived type.
initialize-onlyinitialize-only CamposFields El valor sólo se puede inicializar y no se puede escribir en él después de la inicialización.The value can only be initialized, and cannot be written after initialization.
instanciainstance Campos, métodos, propiedades y eventosFields, methods, properties, and events Si un miembro no está marcado como static (C# y C++), Shared (Visual Basic), virtual (C# y C++) u Overridable (Visual Basic), es un miembro de instancia (no hay palabra clave de la instancia).If a member is not marked as static (C# and C++), Shared (Visual Basic), virtual (C# and C++), or Overridable (Visual Basic), it is an instance member (there is no instance keyword). En la memoria habrá tantas copias de estos miembros como objetos que los utilicen.There will be as many copies of such members in memory as there are objects that use it.
Literalliteral CamposFields El valor asignado al campo es un valor fijo, conocido en tiempo de compilación, de un tipo de valor integrado.The value assigned to the field is a fixed value, known at compile time, of a built-in value type. Los campos literales, a veces, se conocen como constantes.Literal fields are sometimes referred to as constants.
newslot u overridenewslot or override TodasAll Define cómo interactúa el miembro con los miembros heredados que tienen la misma firma:Defines how the member interacts with inherited members that have the same signature:

newslotnewslot
Oculta los miembros heredados que tienen la misma firma.Hides inherited members that have the same signature.

overrideoverride
Reemplaza la definición de un método virtual heredado.Replaces the definition of an inherited virtual method.

El valor predeterminado es newslot.The default is newslot.
estáticostatic Campos, métodos, propiedades y eventosFields, methods, properties, and events El miembro pertenece al tipo en que está definido, no a una instancia particular del tipo. El miembro existe incluso si no se ha creado ninguna instancia del tipo y lo comparten todas las instancias del tipo.The member belongs to the type it is defined on, not to a particular instance of the type; the member exists even if an instance of the type is not created, and it is shared among all instances of the type.
virtualvirtual Métodos, propiedades y eventosMethods, properties, and events Un tipo derivado puede implementar el método, que se puede invocar estática o dinámicamente.The method can be implemented by a derived type and can be invoked either statically or dynamically. Si se usa la invocación dinámica, el tipo de la instancia que hace la llamada en tiempo de ejecución (en lugar del tipo conocido en tiempo de compilación) determina a qué implementación del método se llama.If dynamic invocation is used, the type of the instance that makes the call at run time (rather than the type known at compile time) determines which implementation of the method is called. Para invocar un método virtual de manera estática, es posible que haya que convertir la variable en un tipo que use la versión deseada del método.To invoke a virtual method statically, the variable might have to be cast to a type that uses the desired version of the method.

SobrecargaOverloading

Cada miembro de tipo tiene una firma única.Each type member has a unique signature. Las firmas de método están formadas por el nombre del método y una lista de parámetros (el orden y los tipos de los argumentos del método).Method signatures consist of the method name and a parameter list (the order and types of the method's arguments). Se pueden definir varios métodos con el mismo nombre dentro un tipo, siempre y cuando sus firmas sean distintas.Multiple methods with the same name can be defined within a type as long as their signatures differ. Cuando se definen dos o más métodos con el mismo nombre se dice que el método está sobrecargado.When two or more methods with the same name are defined, the method is said to be overloaded. Por ejemplo, en System.Char, se reemplaza el método IsDigit.For example, in System.Char, the IsDigit method is overloaded. Un método toma un argumento de tipo Char.One method takes a Char. El otro método toma un argumento de tipo String y un argumento de tipo Int32.The other method takes a String and an Int32.

Nota

El tipo de valor devuelto no se considera parte de la firma de un método.The return type is not considered part of a method's signature. Es decir, no se pueden sobrecargar los métodos si solo difieren en el tipo de valor devuelto.That is, methods cannot be overloaded if they differ only by return type.

Heredar, reemplazar y ocultar miembrosInheriting, Overriding, and Hiding Members

Un tipo derivado hereda todos los miembros de su tipo base, es decir, estos miembros se definen en el tipo derivado y están disponibles para él.A derived type inherits all members of its base type; that is, these members are defined on, and available to, the derived type. El comportamiento o cualidades de los miembros heredados se puede modificar de dos maneras:The behavior or qualities of inherited members can be modified in two ways:

  • Un tipo derivado puede ocultar un miembro heredado definiendo un nuevo miembro con la misma firma.A derived type can hide an inherited member by defining a new member with the same signature. Esto puede hacerse para convertir un miembro público en privado o para definir un nuevo comportamiento para un método heredado que está marcado como final.This might be done to make a previously public member private or to define new behavior for an inherited method that is marked as final.

  • Un tipo derivado puede reemplazar a un método virtual heredado.A derived type can override an inherited virtual method. El método de reemplazo proporciona una nueva definición del método que se invocará según el tipo del valor en tiempo de ejecución y no el tipo de la variable conocido en tiempo de compilación.The overriding method provides a new definition of the method that will be invoked based on the type of the value at run time rather than the type of the variable known at compile time. Un método puede invalidar un método virtual únicamente si el método virtual no está marcado como final y el nuevo método es, al menos, tan accesible como el método virtual.A method can override a virtual method only if the virtual method is not marked as final and the new method is at least as accessible as the virtual method.

Vea tambiénSee also