Conceptos básicosBasic concepts

Inicio de la aplicaciónApplication Startup

Un ensamblado que tiene un punto de entrada se denomina un aplicación.An assembly that has an entry point is called an application. Cuando una aplicación es ejecutar una nueva dominio de aplicación se crea.When an application is run, a new application domain is created. Pueden existir varias creaciones de instancias diferentes de una aplicación en el mismo equipo al mismo tiempo, y cada uno tiene su propio dominio de aplicación.Several different instantiations of an application may exist on the same machine at the same time, and each has its own application domain.

Un dominio de aplicación habilita el aislamiento de aplicaciones de forma que actúa como contenedor de estado de la aplicación.An application domain enables application isolation by acting as a container for application state. Un dominio de aplicación actúa como un contenedor y el límite de los tipos definidos en la aplicación y las bibliotecas de clases que utiliza.An application domain acts as a container and boundary for the types defined in the application and the class libraries it uses. Los tipos cargados en un dominio de aplicación son distintos de los mismos tipos cargados en otro dominio de aplicación y las instancias de objetos no se comparten directamente entre dominios de aplicación.Types loaded into one application domain are distinct from the same type loaded into another application domain, and instances of objects are not directly shared between application domains. Por ejemplo, cada dominio de aplicación tiene su propia copia de variables estáticas para estos tipos, y un constructor estático para un tipo se ejecuta como máximo una vez por dominio de aplicación.For instance, each application domain has its own copy of static variables for these types, and a static constructor for a type is run at most once per application domain. Las implementaciones son gratis proporcionar mecanismos o directivas específicas de la implementación para la creación y destrucción de dominios de aplicación.Implementations are free to provide implementation-specific policy or mechanisms for the creation and destruction of application domains.

Inicio de la aplicación se produce cuando el entorno de ejecución llama a un método designado, que se conoce como punto de entrada de la aplicación.Application startup occurs when the execution environment calls a designated method, which is referred to as the application's entry point. Este método de punto de entrada siempre se denomina Mainy puede tener uno de las firmas siguientes:This entry point method is always named Main, and can have one of the following signatures:

static void Main() {...}

static void Main(string[] args) {...}

static int Main() {...}

static int Main(string[] args) {...}

Como se muestra, el punto de entrada, opcionalmente, puede devolver un int valor.As shown, the entry point may optionally return an int value. Esto devuelve el valor se utiliza en la finalización de la aplicación (finalización de la aplicación).This return value is used in application termination (Application termination).

El punto de entrada podría tener opcionalmente un parámetro formal.The entry point may optionally have one formal parameter. El parámetro puede tener cualquier nombre, pero el tipo del parámetro debe ser string[].The parameter may have any name, but the type of the parameter must be string[]. Si el parámetro formal está presente, el entorno de ejecución crea y pasa un string[] argumento que contiene los argumentos de línea de comandos que especificó cuando se inició la aplicación.If the formal parameter is present, the execution environment creates and passes a string[] argument containing the command-line arguments that were specified when the application was started. El string[] argumento nunca es null, pero puede tener una longitud de cero si no se especificó ningún argumento de línea de comandos.The string[] argument is never null, but it may have a length of zero if no command-line arguments were specified.

Puesto que C# admite la sobrecarga de métodos, una clase o estructura puede contener varias definiciones de algún método, siempre que cada una tiene una firma diferente.Since C# supports method overloading, a class or struct may contain multiple definitions of some method, provided each has a different signature. Sin embargo, dentro de un único programa, ninguna clase o estructura la puede contener más de un método llamado Main cuya definición es apta para usarse como un punto de entrada de la aplicación.However, within a single program, no class or struct may contain more than one method called Main whose definition qualifies it to be used as an application entry point. Otras versiones sobrecargadas de Main se permiten, sin embargo, siempre que tengan más de un parámetro o su único parámetro no sea de tipo string[].Other overloaded versions of Main are permitted, however, provided they have more than one parameter, or their only parameter is other than type string[].

Una aplicación puede estar formada por varias clases o structs.An application can be made up of multiple classes or structs. Es posible que más de una de estas clases o structs que contiene un método llamado Main cuya definición es apta para usarse como un punto de entrada de la aplicación.It is possible for more than one of these classes or structs to contain a method called Main whose definition qualifies it to be used as an application entry point. En tales casos, debe usarse un mecanismo externo (por ejemplo, una opción del compilador de línea de comandos) para seleccionar uno de estos Main métodos como punto de entrada.In such cases, an external mechanism (such as a command-line compiler option) must be used to select one of these Main methods as the entry point.

En C#, todos los métodos deben definirse como un miembro de una clase o struct.In C#, every method must be defined as a member of a class or struct. Normalmente, la accesibilidad declarada (accesibilidad declarada) de un método viene determinada por los modificadores de acceso (modificadores de acceso) especificado en su declaración y del mismo modo declarado accesibilidad de un tipo se determina mediante los modificadores de acceso especificados en su declaración.Ordinarily, the declared accessibility (Declared accessibility) of a method is determined by the access modifiers (Access modifiers) specified in its declaration, and similarly the declared accessibility of a type is determined by the access modifiers specified in its declaration. En el orden de un método determinado de un tipo determinado para poder llamar a, el tipo y el miembro deben ser accesible.In order for a given method of a given type to be callable, both the type and the member must be accessible. Sin embargo, el punto de entrada de la aplicación es un caso especial.However, the application entry point is a special case. En concreto, el entorno de ejecución puede tener acceso a punto de entrada de la aplicación, independientemente de su accesibilidad declarada y sin tener en cuenta la accesibilidad declarada de sus declaraciones de tipo envolvente.Specifically, the execution environment can access the application's entry point regardless of its declared accessibility and regardless of the declared accessibility of its enclosing type declarations.

El método de punto de entrada de aplicación no puede ser en una declaración de clase genérica.The application entry point method may not be in a generic class declaration.

En todos los demás aspectos, los métodos de punto de entrada se comportan como los que no son puntos de entrada.In all other respects, entry point methods behave like those that are not entry points.

Finalización de la aplicaciónApplication termination

Finalización de la aplicación devuelve el control al entorno de ejecución.Application termination returns control to the execution environment.

Si el tipo de valor devuelto de la aplicación punto de entrada método es int, el valor devuelto actúa como la aplicación código de estado de terminación.If the return type of the application's entry point method is int, the value returned serves as the application's termination status code. El propósito de este código es permitir la comunicación de éxito o error para el entorno de ejecución.The purpose of this code is to allow communication of success or failure to the execution environment.

Si el tipo de valor devuelto del método de punto de entrada es void, llegar a la llave de cierre (}) que termina ese método o ejecutar un return instrucción que no contiene una expresión, da como resultado un código de estado de terminación 0.If the return type of the entry point method is void, reaching the right brace (}) which terminates that method, or executing a return statement that has no expression, results in a termination status code of 0.

Antes de la finalización de la aplicación, se llaman a destructores para todos sus objetos que aún no se han recolectado, a menos que se ha suprimido esta limpieza (mediante una llamada al método de biblioteca GC.SuppressFinalize, por ejemplo).Prior to an application's termination, destructors for all of its objects that have not yet been garbage collected are called, unless such cleanup has been suppressed (by a call to the library method GC.SuppressFinalize, for example).

DeclaracionesDeclarations

Las declaraciones en un programa de C# definen los elementos constituyentes del programa.Declarations in a C# program define the constituent elements of the program. Programas de C# se organizan mediante espacios de nombres (espacios de nombres), que puede contener el tipo de declaraciones y las declaraciones de espacio de nombres anidado.C# programs are organized using namespaces (Namespaces), which can contain type declarations and nested namespace declarations. Declaraciones de tipos (declaraciones de tipo) se usan para definir clases (clases), estructuras (Structs), interfaces (Interfaces ), enumeraciones (enumeraciones) y los delegados (delegados).Type declarations (Type declarations) are used to define classes (Classes), structs (Structs), interfaces (Interfaces), enums (Enums), and delegates (Delegates). Los tipos de miembros permitidos en una declaración de tipos dependen de la forma de la declaración de tipos.The kinds of members permitted in a type declaration depend on the form of the type declaration. Por ejemplo, las declaraciones de clase pueden contener declaraciones de constantes (constantes), campos (campos), los métodos (métodos), propiedades ( Propiedades), los eventos (eventos), los indizadores (indizadores), operadores (operadores), constructores de instancias ( Constructores de instancias), los constructores estáticos (constructores estáticos), los destructores (destructores) y los tipos anidados (tiposanidados).For instance, class declarations can contain declarations for constants (Constants), fields (Fields), methods (Methods), properties (Properties), events (Events), indexers (Indexers), operators (Operators), instance constructors (Instance constructors), static constructors (Static constructors), destructors (Destructors), and nested types (Nested types).

Una declaración define un nombre en el espacio de declaración al que pertenece la declaración.A declaration defines a name in the declaration space to which the declaration belongs. Excepto para sobrecargar los miembros (firmas y sobrecarga), es un error de tiempo de compilación tiene dos o más declaraciones que introducen miembros con el mismo nombre en un espacio de declaración.Except for overloaded members (Signatures and overloading), it is a compile-time error to have two or more declarations that introduce members with the same name in a declaration space. Nunca es posible que un espacio de declaración contener distintos tipos de miembros con el mismo nombre.It is never possible for a declaration space to contain different kinds of members with the same name. Por ejemplo, un espacio de declaración nunca puede contener un campo y un método con el mismo nombre.For example, a declaration space can never contain a field and a method by the same name.

Hay varios tipos diferentes de espacios de declaración, como se describe en la siguiente.There are several different types of declaration spaces, as described in the following.

  • En todos los archivos de código fuente de un programa, namespace_member_declarations con ningún envolvente namespace_declaration son miembros de un espacio de declaración combinado único denominado el global espacio de declaración.Within all source files of a program, namespace_member_declarations with no enclosing namespace_declaration are members of a single combined declaration space called the global declaration space.
  • En todos los archivos de código fuente de un programa, namespace_member_declarations dentro de namespace_declarationque tienen el mismo nombre completo del espacio de nombres son miembros de una sola declaración combinada espacio.Within all source files of a program, namespace_member_declarations within namespace_declarations that have the same fully qualified namespace name are members of a single combined declaration space.
  • Cada clase, struct o declaración de interfaz crea un nuevo espacio de declaración.Each class, struct, or interface declaration creates a new declaration space. Los nombres se incluyen en este espacio de declaración mediante class_member_declarations, struct_member_declarations, interface_member_declarations, o tipo_parámetros.Names are introduced into this declaration space through class_member_declarations, struct_member_declarations, interface_member_declarations, or type_parameters. Excepto para el constructor de instancia sobrecargada declaraciones y un constructor estático declaraciones, una clase o struct no pueden contener una declaración de miembro con el mismo nombre que la clase o estructura.Except for overloaded instance constructor declarations and static constructor declarations, a class or struct cannot contain a member declaration with the same name as the class or struct. Una clase, estructura o interfaz permite la declaración de métodos sobrecargados e indizadores.A class, struct, or interface permits the declaration of overloaded methods and indexers. Además, una clase o estructura permite la declaración de operadores y constructores de instancias sobrecargadas.Furthermore, a class or struct permits the declaration of overloaded instance constructors and operators. Por ejemplo, una clase, struct o interfaz puede contener varias declaraciones de método con el mismo nombre, siempre que estas declaraciones de método difieren en su firma (firmas y sobrecarga).For example, a class, struct, or interface may contain multiple method declarations with the same name, provided these method declarations differ in their signature (Signatures and overloading). Tenga en cuenta que las clases base no contribuyen al espacio de declaración de una clase y las interfaces base no contribuyen al espacio de declaración de una interfaz.Note that base classes do not contribute to the declaration space of a class, and base interfaces do not contribute to the declaration space of an interface. Por lo tanto, una clase derivada o una interfaz puede declarar a un miembro con el mismo nombre que un miembro heredado.Thus, a derived class or interface is allowed to declare a member with the same name as an inherited member. Se dice que un miembro de este tipo ocultar el miembro heredado.Such a member is said to hide the inherited member.
  • Cada declaración de delegado crea un nuevo espacio de declaración.Each delegate declaration creates a new declaration space. Los nombres se incluyen en este espacio de declaración a través de parámetros formales (fixed_parameters y parameter_arrays) y tipo_parámetros.Names are introduced into this declaration space through formal parameters (fixed_parameters and parameter_arrays) and type_parameters.
  • Cada declaración de enumeración crea un nuevo espacio de declaración.Each enumeration declaration creates a new declaration space. Los nombres se incluyen en este espacio de declaración mediante enum_member_declarations.Names are introduced into this declaration space through enum_member_declarations.
  • Cada declaración de método, declaración de indexador, declaración del operador, la declaración de constructor de instancia y función anónima crean un nuevo espacio de declaración que se llama a un espacio de declaración de variable local.Each method declaration, indexer declaration, operator declaration, instance constructor declaration and anonymous function creates a new declaration space called a local variable declaration space. Los nombres se incluyen en este espacio de declaración a través de parámetros formales (fixed_parameters y parameter_arrays) y tipo_parámetros.Names are introduced into this declaration space through formal parameters (fixed_parameters and parameter_arrays) and type_parameters. El cuerpo del miembro de función o función anónima, si existe, se considera que se puede anidar dentro del espacio de declaración de variable local.The body of the function member or anonymous function, if any, is considered to be nested within the local variable declaration space. Es un error para un espacio de declaración de variable local y un espacio de declaración de variable local anidado contengan elementos con el mismo nombre.It is an error for a local variable declaration space and a nested local variable declaration space to contain elements with the same name. Por lo tanto, dentro de un espacio de declaración anidado no es posible declarar a una variable local variable o constante con el mismo nombre que una variable local o una constante en un espacio de declaración envolvente.Thus, within a nested declaration space it is not possible to declare a local variable or constant with the same name as a local variable or constant in an enclosing declaration space. Es posible que dos espacios de declaración contengan elementos con el mismo nombre siempre y cuando ningún espacio de declaración contenga el otro.It is possible for two declaration spaces to contain elements with the same name as long as neither declaration space contains the other.
  • Cada bloque o switch_block , así como un para, foreach y mediante instrucción, crea un espacio de declaración de variable local para las variables locales y constantes locales.Each block or switch_block , as well as a for, foreach and using statement, creates a local variable declaration space for local variables and local constants . Los nombres se incluyen en este espacio de declaración mediante local_variable_declarations y local_constant_declarations.Names are introduced into this declaration space through local_variable_declarations and local_constant_declarations. Tenga en cuenta que los bloques que se producen como o dentro del cuerpo de un miembro de función o función anónima están anidados dentro del espacio de declaración de variable local declarado por esas funciones para sus parámetros.Note that blocks that occur as or within the body of a function member or anonymous function are nested within the local variable declaration space declared by those functions for their parameters. Por lo tanto es un error, por ejemplo, tener un método con un parámetro del mismo nombre y una variable local.Thus it is an error to have e.g. a method with a local variable and a parameter of the same name.
  • Cada bloque o switch_block crea un espacio de declaración independiente para las etiquetas.Each block or switch_block creates a separate declaration space for labels. Los nombres se incluyen en este espacio de declaración mediante labeled_statements y los nombres se identifican mediante goto_statements.Names are introduced into this declaration space through labeled_statements, and the names are referenced through goto_statements. El etiqueta espacio de declaración de un bloque incluye bloques anidados.The label declaration space of a block includes any nested blocks. Por lo tanto, dentro de un bloque anidado no es posible declarar una etiqueta con el mismo nombre que una etiqueta en un bloque de inclusión.Thus, within a nested block it is not possible to declare a label with the same name as a label in an enclosing block.

El orden textual en que se declaran los nombres suele ser ninguna importancia.The textual order in which names are declared is generally of no significance. En concreto, no es significativo para la declaración y el uso de espacios de nombres, constantes, métodos, propiedades, eventos, indizadores, operadores, constructores de instancias, destructores, constructores estáticos y tipos de orden textual.In particular, textual order is not significant for the declaration and use of namespaces, constants, methods, properties, events, indexers, operators, instance constructors, destructors, static constructors, and types. El orden de declaración es significativo de las maneras siguientes:Declaration order is significant in the following ways:

  • Orden de declaración de las declaraciones de campo y declaraciones de variable local determina el orden en que se ejecutan sus inicializadores (si existe).Declaration order for field declarations and local variable declarations determines the order in which their initializers (if any) are executed.
  • Se deben definir las variables locales antes de utilizarlas (ámbitos).Local variables must be defined before they are used (Scopes).
  • Orden de declaración de las declaraciones de miembro de enumeración (miembros de enumeración) es significativo cuando constant_expression los valores se omiten.Declaration order for enum member declarations (Enum members) is significant when constant_expression values are omitted.

El espacio de declaración del espacio de nombres es "de extremo abierto" y espacio de nombres dos declaraciones con el mismo nombre completo contribuyen al mismo espacio de declaración.The declaration space of a namespace is "open ended", and two namespace declarations with the same fully qualified name contribute to the same declaration space. Por ejemploFor example

namespace Megacorp.Data
{
    class Customer
    {
        ...
    }
}

namespace Megacorp.Data
{
    class Order
    {
        ...
    }
}

Las dos declaraciones de espacio de nombres anteriores contribuyen al mismo espacio de declaración, en este caso declarar dos clases con los nombres completos Megacorp.Data.Customer y Megacorp.Data.Order.The two namespace declarations above contribute to the same declaration space, in this case declaring two classes with the fully qualified names Megacorp.Data.Customer and Megacorp.Data.Order. Dado que las dos declaraciones contribuyen al mismo espacio de declaración, habría causado un error en tiempo de compilación si cada una contiene una declaración de una clase con el mismo nombre.Because the two declarations contribute to the same declaration space, it would have caused a compile-time error if each contained a declaration of a class with the same name.

Según lo especificado anteriormente, el espacio de declaración de un bloque incluye bloques anidados.As specified above, the declaration space of a block includes any nested blocks. Por lo tanto, en el ejemplo siguiente, la F y G métodos producen un error en tiempo de compilación porque el nombre i se declara en el bloque externo y no se puede volver a declarar en el bloque interno.Thus, in the following example, the F and G methods result in a compile-time error because the name i is declared in the outer block and cannot be redeclared in the inner block. Sin embargo, el H y I métodos son válidos porque los dos idel se declaran en bloques independientes no anidados.However, the H and I methods are valid since the two i's are declared in separate non-nested blocks.

class A
{
    void F() {
        int i = 0;
        if (true) {
            int i = 1;            
        }
    }

    void G() {
        if (true) {
            int i = 0;
        }
        int i = 1;                
    }

    void H() {
        if (true) {
            int i = 0;
        }
        if (true) {
            int i = 1;
        }
    }

    void I() {
        for (int i = 0; i < 10; i++)
            H();
        for (int i = 0; i < 10; i++)
            H();
    }
}

MiembrosMembers

Los espacios de nombres y tipos tienen miembros.Namespaces and types have members. Los miembros de una entidad están generalmente disponibles mediante el uso de un nombre completo que se inicia con una referencia a la entidad, seguido por un "." símbolo (token), seguido del nombre del miembro.The members of an entity are generally available through the use of a qualified name that starts with a reference to the entity, followed by a "." token, followed by the name of the member.

Los miembros de un tipo se declaren en la declaración de tipos o heredado de la clase base del tipo.Members of a type are either declared in the type declaration or inherited from the base class of the type. Cuando un tipo hereda de una clase base, todos los miembros de la clase base, excepto los constructores de instancias, destructores y constructores estáticos, se convierten en miembros del tipo derivado.When a type inherits from a base class, all members of the base class, except instance constructors, destructors and static constructors, become members of the derived type. La accesibilidad declarada de un miembro de clase base no controla si el miembro se hereda, herencia se amplía a cualquier miembro que no es un constructor de instancia, un constructor estático o un destructor.The declared accessibility of a base class member does not control whether the member is inherited—inheritance extends to any member that isn't an instance constructor, static constructor, or destructor. Sin embargo, un miembro heredado puede no estar accesible en un tipo derivado, ya sea a causa de su accesibilidad declarada (accesibilidad declarada) o porque está oculto por una declaración en el propio tipo (ocultar mediante herencia).However, an inherited member may not be accessible in a derived type, either because of its declared accessibility (Declared accessibility) or because it is hidden by a declaration in the type itself (Hiding through inheritance).

Miembros de NamespaceNamespace members

Los espacios de nombres y tipos que no tienen ningún espacio de nombres envolvente son miembros de la espacio de nombres global.Namespaces and types that have no enclosing namespace are members of the global namespace. Esto corresponde directamente a los nombres declarados en el espacio de declaración global.This corresponds directly to the names declared in the global declaration space.

Espacios de nombres y tipos declarados dentro de un espacio de nombres son miembros de ese espacio de nombres.Namespaces and types declared within a namespace are members of that namespace. Esto corresponde directamente a los nombres declarados en el espacio de declaración del espacio de nombres.This corresponds directly to the names declared in the declaration space of the namespace.

Los espacios de nombres no tienen restricciones de acceso.Namespaces have no access restrictions. No es posible declarar espacios de nombres privado, protegido o interno y espacios de nombres siempre son accesibles públicamente.It is not possible to declare private, protected, or internal namespaces, and namespace names are always publicly accessible.

Miembros de estructuraStruct members

Los miembros de un struct son los miembros declarados en la estructura y los miembros heredados de la clase base directa del struct System.ValueType y la clase base indirecta object.The members of a struct are the members declared in the struct and the members inherited from the struct's direct base class System.ValueType and the indirect base class object.

Los miembros de un tipo simple se corresponden directamente a los miembros de lo alias de tipo struct mediante el tipo simple:The members of a simple type correspond directly to the members of the struct type aliased by the simple type:

  • Los miembros de sbyte son los miembros de la System.SByte struct.The members of sbyte are the members of the System.SByte struct.
  • Los miembros de byte son los miembros de la System.Byte struct.The members of byte are the members of the System.Byte struct.
  • Los miembros de short son los miembros de la System.Int16 struct.The members of short are the members of the System.Int16 struct.
  • Los miembros de ushort son los miembros de la System.UInt16 struct.The members of ushort are the members of the System.UInt16 struct.
  • Los miembros de int son los miembros de la System.Int32 struct.The members of int are the members of the System.Int32 struct.
  • Los miembros de uint son los miembros de la System.UInt32 struct.The members of uint are the members of the System.UInt32 struct.
  • Los miembros de long son los miembros de la System.Int64 struct.The members of long are the members of the System.Int64 struct.
  • Los miembros de ulong son los miembros de la System.UInt64 struct.The members of ulong are the members of the System.UInt64 struct.
  • Los miembros de char son los miembros de la System.Char struct.The members of char are the members of the System.Char struct.
  • Los miembros de float son los miembros de la System.Single struct.The members of float are the members of the System.Single struct.
  • Los miembros de double son los miembros de la System.Double struct.The members of double are the members of the System.Double struct.
  • Los miembros de decimal son los miembros de la System.Decimal struct.The members of decimal are the members of the System.Decimal struct.
  • Los miembros de bool son los miembros de la System.Boolean struct.The members of bool are the members of the System.Boolean struct.

Miembros de enumeraciónEnumeration members

Los miembros de una enumeración son las constantes que se declaran en la enumeración y los miembros heredados de la clase base directa de la enumeración System.Enum y las clases base indirectas System.ValueType y object.The members of an enumeration are the constants declared in the enumeration and the members inherited from the enumeration's direct base class System.Enum and the indirect base classes System.ValueType and object.

Miembros de la claseClass members

Los miembros de una clase son los miembros declarados en la clase y los miembros heredados de la clase base (excepto para la clase object que no tiene clase base).The members of a class are the members declared in the class and the members inherited from the base class (except for class object which has no base class). Los miembros heredados de la clase base incluyen las constantes, campos, métodos, propiedades, eventos, indizadores, operadores y tipos de la clase base, pero no los constructores de instancias, destructores y constructores estáticos de la clase base.The members inherited from the base class include the constants, fields, methods, properties, events, indexers, operators, and types of the base class, but not the instance constructors, destructors and static constructors of the base class. Los miembros de clase base se heredan con independencia de su accesibilidad.Base class members are inherited without regard to their accessibility.

Una declaración de clase puede contener declaraciones de constantes, campos, métodos, propiedades, eventos, indizadores, operadores, constructores de instancias, destructores, constructores estáticos y tipos.A class declaration may contain declarations of constants, fields, methods, properties, events, indexers, operators, instance constructors, destructors, static constructors and types.

Los miembros de object y string corresponden directamente a los miembros de los tipos de clase alias:The members of object and string correspond directly to the members of the class types they alias:

  • Los miembros de object son los miembros de la System.Object clase.The members of object are the members of the System.Object class.
  • Los miembros de string son los miembros de la System.String clase.The members of string are the members of the System.String class.

Miembros de interfazInterface members

Los miembros de una interfaz son los miembros declarados en la interfaz y en todas las interfaces base de la interfaz.The members of an interface are the members declared in the interface and in all base interfaces of the interface. Los miembros de clase object no son estrictamente hablando, los miembros de cualquier interfaz (miembros de interfaz).The members in class object are not, strictly speaking, members of any interface (Interface members). Sin embargo, los miembros de clase object están disponibles a través de la búsqueda de miembros en cualquier tipo de interfaz (búsqueda de miembros).However, the members in class object are available via member lookup in any interface type (Member lookup).

Miembros de la matrizArray members

Los miembros de la matriz son los miembros heredados de la clase System.Array.The members of an array are the members inherited from class System.Array.

Miembros de delegadoDelegate members

Los miembros de un delegado son los miembros heredados de la clase System.Delegate.The members of a delegate are the members inherited from class System.Delegate.

Acceso a miembrosMember access

Las declaraciones de miembros permiten un control sobre el acceso de miembro.Declarations of members allow control over member access. La accesibilidad de un miembro se establece mediante la accesibilidad declarada (accesibilidad declarada) del miembro combinada con la accesibilidad del tipo contenedor inmediato, si existe.The accessibility of a member is established by the declared accessibility (Declared accessibility) of the member combined with the accessibility of the immediately containing type, if any.

Cuando se permite el acceso a un miembro concreto, se dice que el miembro sea accesible.When access to a particular member is allowed, the member is said to be accessible. Por el contrario, cuando no se permite el acceso a un miembro determinado, el miembro se dice que inaccesible.Conversely, when access to a particular member is disallowed, the member is said to be inaccessible. Se permite el acceso a un miembro cuando se incluye la ubicación del texto en el que realiza el acceso en el dominio de accesibilidad (dominios de accesibilidad) del miembro.Access to a member is permitted when the textual location in which the access takes place is included in the accessibility domain (Accessibility domains) of the member.

Accesibilidad declaradaDeclared accessibility

El accesibilidad declarada de un miembro puede ser uno de los siguientes:The declared accessibility of a member can be one of the following:

  • Público, que se selecciona mediante la inclusión de un public modificador en la declaración del miembro.Public, which is selected by including a public modifier in the member declaration. El significado intuitivo de public es "acceso no restringido".The intuitive meaning of public is "access not limited".
  • Protegido, que se selecciona mediante la inclusión de un protected modificador en la declaración del miembro.Protected, which is selected by including a protected modifier in the member declaration. El significado intuitivo de protected es "acceso limitado a la clase contenedora o a tipos derivado de la clase contenedora".The intuitive meaning of protected is "access limited to the containing class or types derived from the containing class".
  • Interna, que se selecciona mediante la inclusión de un internal modificador en la declaración del miembro.Internal, which is selected by including an internal modifier in the member declaration. El significado intuitivo de internal es "acceso limitado a este programa".The intuitive meaning of internal is "access limited to this program".
  • Protected internal (es decir, protegidos o internos), que está seleccionada si se incluyen un protected y un internal modificador en la declaración del miembro.Protected internal (meaning protected or internal), which is selected by including both a protected and an internal modifier in the member declaration. El significado intuitivo de protected internal es "acceso limitado a este programa o tipos derivados de la clase contenedora".The intuitive meaning of protected internal is "access limited to this program or types derived from the containing class".
  • Private, que se selecciona mediante la inclusión de un private modificador en la declaración del miembro.Private, which is selected by including a private modifier in the member declaration. El significado intuitivo de private es "acceso limitado al tipo contenedor".The intuitive meaning of private is "access limited to the containing type".

Dependiendo del contexto en el que tiene una declaración de miembro produce, se permiten solo determinados tipos de accesibilidad declarada.Depending on the context in which a member declaration takes place, only certain types of declared accessibility are permitted. Además, cuando una declaración de miembro no incluye ningún modificador de acceso, el contexto en el que tiene lugar la declaración determina la accesibilidad declarada predeterminada.Furthermore, when a member declaration does not include any access modifiers, the context in which the declaration takes place determines the default declared accessibility.

  • Los espacios de nombres tienen implícitamente public accesibilidad declarada.Namespaces implicitly have public declared accessibility. Modificadores de acceso no se permiten en declaraciones de espacio de nombres.No access modifiers are allowed on namespace declarations.
  • Pueden tener tipos declarados en unidades de compilación o espacios de nombres public o internal declarado el valor predeterminado y accesibilidad internal accesibilidad declarada.Types declared in compilation units or namespaces can have public or internal declared accessibility and default to internal declared accessibility.
  • Los miembros de clase pueden tener cualquiera de los cinco tipos de accesibilidad declarada y de forma predeterminada private accesibilidad declarada.Class members can have any of the five kinds of declared accessibility and default to private declared accessibility. (Tenga en cuenta que un tipo declarado como un miembro de una clase puede tener cualquiera de los cinco tipos de accesibilidad declarada, mientras que un tipo declarado como un miembro de un espacio de nombres puede tener solo public o internal accesibilidad declarada.)(Note that a type declared as a member of a class can have any of the five kinds of declared accessibility, whereas a type declared as a member of a namespace can have only public or internal declared accessibility.)
  • Pueden tener miembros de struct public, internal, o private declarado el valor predeterminado y accesibilidad private accesibilidad declarada porque structs están sellados implícitamente.Struct members can have public, internal, or private declared accessibility and default to private declared accessibility because structs are implicitly sealed. No pueden tener miembros de estructura introducidos en un struct (que es, no heredan esa estructura) protected o protected internal accesibilidad declarada.Struct members introduced in a struct (that is, not inherited by that struct) cannot have protected or protected internal declared accessibility. (Tenga en cuenta que un tipo declarado como un miembro de un struct puede tener public, internal, o private declara la accesibilidad, mientras que un tipo declarado como un miembro de un espacio de nombres puede tener solo public o internal accesibilidad declarada.)(Note that a type declared as a member of a struct can have public, internal, or private declared accessibility, whereas a type declared as a member of a namespace can have only public or internal declared accessibility.)
  • Los miembros de interfaz tienen implícitamente public accesibilidad declarada.Interface members implicitly have public declared accessibility. Modificadores de acceso no se permiten en las declaraciones de miembros de interfaz.No access modifiers are allowed on interface member declarations.
  • Los miembros de enumeración tienen implícitamente public accesibilidad declarada.Enumeration members implicitly have public declared accessibility. Modificadores de acceso no se permiten en declaraciones de miembro de enumeración.No access modifiers are allowed on enumeration member declarations.

Dominios de accesibilidadAccessibility domains

El dominio de accesibilidad de un miembro consta de las secciones del texto del programa en el que se permite el acceso al miembro (posiblemente separadas).The accessibility domain of a member consists of the (possibly disjoint) sections of program text in which access to the member is permitted. Para fines de definir el dominio de accesibilidad de un miembro, un miembro se dice que nivel superior si no se ha declarado dentro de un tipo, y se dice que ser un miembro anidada si se declara dentro de otro tipo.For purposes of defining the accessibility domain of a member, a member is said to be top-level if it is not declared within a type, and a member is said to be nested if it is declared within another type. Además, el texto de programa de un programa se define como todos los programa texto contenido en todos los archivos de código fuente del programa, y el texto del programa de un tipo se define como todos los programa texto contenido en el type_declarations de ese tipo (incluidos, posiblemente, los tipos que están anidados dentro del tipo).Furthermore, the program text of a program is defined as all program text contained in all source files of the program, and the program text of a type is defined as all program text contained in the type_declarations of that type (including, possibly, types that are nested within the type).

El dominio de accesibilidad de un tipo predefinido (como object, int, o double) es ilimitado.The accessibility domain of a predefined type (such as object, int, or double) is unlimited.

El dominio de accesibilidad de un nivel superior sin enlazar tipo T (dependientes e independientes tipos) que se declara en un programa P se define como sigue:The accessibility domain of a top-level unbound type T (Bound and unbound types) that is declared in a program P is defined as follows:

  • Si la accesibilidad declarada de T es public, el dominio de accesibilidad de T es el texto del programa P y cualquier programa que hace referencia a P.If the declared accessibility of T is public, the accessibility domain of T is the program text of P and any program that references P.
  • Si la accesibilidad declarada de T es internal, el dominio de accesibilidad de T es el texto de programa de P.If the declared accessibility of T is internal, the accessibility domain of T is the program text of P.

Desde estas definiciones se deduce que el dominio de accesibilidad de un tipo sin enlazar de nivel superior es, al menos el texto de programa del programa en el que ese tipo se declara.From these definitions it follows that the accessibility domain of a top-level unbound type is always at least the program text of the program in which that type is declared.

El dominio de accesibilidad para un tipo construido T<A1, ..., An> es la intersección del dominio de accesibilidad del tipo genérico sin enlazar T y los dominios de accesibilidad de los argumentos de tipo A1, ..., An.The accessibility domain for a constructed type T<A1, ..., An> is the intersection of the accessibility domain of the unbound generic type T and the accessibility domains of the type arguments A1, ..., An.

El dominio de accesibilidad de un miembro anidado M declarados en un tipo T dentro de un programa P se define como sigue (teniendo en cuenta que M probablemente sea 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 itself may possibly 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, permiten D será la unión del texto del programa P y el texto del programa de cualquier tipo derivado de T, que se declara fuera P.If the declared accessibility of M is protected internal, let D be the union of the program text of P and the program text of any type derived from T, which is declared outside P. El dominio de accesibilidad de M es la intersección del dominio de accesibilidad de T con D.The accessibility domain of M is the intersection of the accessibility domain of T with D.
  • Si la accesibilidad declarada de M es protected, permiten D será la unión del texto del programa T y el texto del programa de cualquier tipo derivado de T.If the declared accessibility of M is protected, let D be the union of the program text of T and the program text of any type derived from T. El dominio de accesibilidad de M es la intersección del dominio de accesibilidad de T con D.The accessibility domain of M is the intersection of the accessibility domain of T with D.
  • 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.

Desde estas definiciones se deduce que el dominio de accesibilidad de un miembro anidado es, al menos el texto de programa del tipo en el que se declara el miembro.From these definitions it follows that the accessibility domain of a nested member is always at least the program text of the type in which the member is declared. Además, se deduce que el dominio de accesibilidad de un miembro nunca es más inclusivo que el dominio de accesibilidad del tipo en el que se declara el miembro.Furthermore, it follows that the accessibility domain of a member is never more inclusive than the accessibility domain of the type in which the member is declared.

En términos intuitivos, cuando un tipo o miembro M es tener acceso a, se evalúan los pasos siguientes para asegurarse de que se permite el acceso:In intuitive terms, when a type or member M is accessed, the following steps are evaluated to ensure that the access is permitted:

  • Primero, if M se declara dentro de un tipo (en oposición a una unidad de compilación o un espacio de nombres), se produce un error de tiempo de compilación si ese tipo no es accesible.First, if M is declared within a type (as opposed to a compilation unit or a namespace), a compile-time error occurs if that type is not accessible.
  • A continuación, si M es public, se permite el acceso.Then, if M is public, the access is permitted.
  • De lo contrario, si M es protected internal, se permite el acceso si se produce dentro del programa en el que M se declara, o si se produce dentro de una clase derivada de la clase en la que M se declara y se realiza a través de la clase derivada tipo de clase (protegido por ejemplo acceder a los miembros).Otherwise, if M is protected internal, the access is permitted if it occurs within the program in which M is declared, or if it occurs within a class derived from the class in which M is declared and takes place through the derived class type (Protected access for instance members).
  • De lo contrario, si M es protected, se permite el acceso si se produce dentro de la clase en el que M se declara, o si se produce dentro de una clase derivada de la clase en la que M se declara y se realiza a través de la clase derivada tipo de clase (protegido por ejemplo acceder a los miembros).Otherwise, if M is protected, the access is permitted if it occurs within the class in which M is declared, or if it occurs within a class derived from the class in which M is declared and takes place through the derived class type (Protected access for instance members).
  • De lo contrario, si M es internal, se permite el acceso si se produce dentro del programa en el que M se declara.Otherwise, if M is internal, the access is permitted if it occurs within the program in which M is declared.
  • De lo contrario, si M es private, se permite el acceso si se produce dentro del tipo en el que M se declara.Otherwise, if M is private, the access is permitted if it occurs within the type in which M is declared.
  • En caso contrario, el tipo o miembro es inaccesible y se produce un error de tiempo de compilación.Otherwise, the type or member is inaccessible, and a compile-time error occurs.

En el ejemploIn the example

public class A
{
    public static int X;
    internal static int Y;
    private static int Z;
}

internal class B
{
    public static int X;
    internal static int Y;
    private static int Z;

    public class C
    {
        public static int X;
        internal static int Y;
        private static int Z;
    }

    private class D
    {
        public static int X;
        internal static int Y;
        private static int Z;
    }
}

las clases y miembros tienen los dominios de accesibilidad siguientes:the classes and members have the following accessibility domains:

  • El dominio de accesibilidad de A y A.X es ilimitado.The accessibility domain of A and A.X is unlimited.
  • El dominio de accesibilidad de A.Y, B, B.X, B.Y, B.C, B.C.X, y B.C.Y es el texto de programa del programa que lo contiene.The accessibility domain of A.Y, B, B.X, B.Y, B.C, B.C.X, and B.C.Y is the program text of the containing program.
  • El dominio de accesibilidad de A.Z es el texto del programa A.The accessibility domain of A.Z is the program text of A.
  • El dominio de accesibilidad de B.Z y B.D es el texto del programa B, incluido el texto del programa B.C y B.D.The accessibility domain of B.Z and B.D is the program text of B, including the program text of B.C and B.D.
  • El dominio de accesibilidad de B.C.Z es el texto del programa B.C.The accessibility domain of B.C.Z is the program text of B.C.
  • El dominio de accesibilidad de B.D.X y B.D.Y es el texto del programa B, incluido el texto del programa B.C y B.D.The accessibility domain of B.D.X and B.D.Y is the program text of B, including the program text of B.C and B.D.
  • El dominio de accesibilidad de B.D.Z es el texto del programa B.D.The accessibility domain of B.D.Z is the program text of B.D.

Como se muestra en el ejemplo siguiente, el dominio de accesibilidad de un miembro nunca es mayor que el de un tipo contenedor.As the example illustrates, the accessibility domain of a member is never larger than that of a containing type. Por ejemplo, aunque todos los X los miembros tienen accesibilidad declarada public, todos excepto A.X tiene dominios de accesibilidad que están restringidos por un tipo contenedor.For example, even though all X members have public declared accessibility, all but A.X have accessibility domains that are constrained by a containing type.

Como se describe en miembros, todos los miembros de una clase base, excepto por ejemplo, constructores, destructores y constructores estáticos, son heredados por tipos derivados.As described in Members, all members of a base class, except for instance constructors, destructors and static constructors, are inherited by derived types. Esto incluye incluso miembros privados de una clase base.This includes even private members of a base class. Sin embargo, el dominio de accesibilidad de un miembro privado incluye sólo el texto de programa del tipo en el que se declara el miembro.However, the accessibility domain of a private member includes only the program text of the type in which the member is declared. En el ejemploIn the example

class A
{
    int x;

    static void F(B b) {
        b.x = 1;        // Ok
    }
}

class B: A
{
    static void F(B b) {
        b.x = 1;        // Error, x not accessible
    }
}

el B clase hereda el miembro privado x desde el A clase.the B class inherits the private member x from the A class. Dado que el miembro es privado, solo es accesible dentro de la class_body de A.Because the member is private, it is only accessible within the class_body of A. Por lo tanto, el acceso a b.x funciona correctamente en el A.F método, pero se produce un error en la B.F método.Thus, the access to b.x succeeds in the A.F method, but fails in the B.F method.

Acceso protegido para miembros de instanciaProtected access for instance members

Cuando un protected se tiene acceso a miembros de instancia fuera del texto de la clase en el que se declara, y cuándo una protected internal se tiene acceso a miembros de instancia fuera del texto de programa del programa en el que se declara, el acceso debe tener lugar dentro de un declaración de clase que deriva de la clase en el que se declara.When a protected instance member is accessed outside the program text of the class in which it is declared, and when a protected internal instance member is accessed outside the program text of the program in which it is declared, the access must take place within a class declaration that derives from the class in which it is declared. Además, el acceso se requiere que tenga lugar a través de una instancia de ese tipo de clase derivada o un tipo de clase construida a partir de él.Furthermore, the access is required to take place through an instance of that derived class type or a class type constructed from it. Esta restricción impide que una clase derivada tengan acceso a miembros protegidos de otras clases derivadas, incluso cuando los miembros se heredan de la misma clase base.This restriction prevents one derived class from accessing protected members of other derived classes, even when the members are inherited from the same base class.

Permiten B ser una clase base que declara un miembro de instancia protegida My permiten D ser una clase que deriva de B.Let B be a base class that declares a protected instance member M, and let D be a class that derives from B. Dentro de la class_body de D, el acceso a M puede tomar uno de los formatos siguientes:Within the class_body of D, access to M can take one of the following forms:

  • Un sin calificar type_name o primary_expression del formulario M.An unqualified type_name or primary_expression of the form M.
  • Un primary_expression del formulario E.M, siempre que el tipo de E es T o una clase derivada de T, donde T es el tipo de clase D, o un tipo de clase construido a partir de DA primary_expression of the form E.M, provided the type of E is T or a class derived from T, where T is the class type D, or a class type constructed from D
  • Un primary_expression del formulario base.M.A primary_expression of the form base.M.

Además de estas formas de acceso, una clase derivada puede tener acceso a un constructor de instancia protegida de una clase base en un constructor_initializer (inicializadores de Constructor).In addition to these forms of access, a derived class can access a protected instance constructor of a base class in a constructor_initializer (Constructor initializers).

En el ejemploIn the example

public class A
{
    protected int x;

    static void F(A a, B b) {
        a.x = 1;        // Ok
        b.x = 1;        // Ok
    }
}

public class B: A
{
    static void F(A a, B b) {
        a.x = 1;        // Error, must access through instance of B
        b.x = 1;        // Ok
    }
}

dentro de A, es posible obtener acceso a x a través de instancias de ambos A y B, ya que en ambos casos el acceso realiza a través de una instancia de A o una clase derivada de A.within A, it is possible to access x through instances of both A and B, since in either case the access takes place through an instance of A or a class derived from A. Sin embargo, dentro de B, no es posible tener acceso x a través de una instancia de A, puesto que A no se deriva de B.However, within B, it is not possible to access x through an instance of A, since A does not derive from B.

En el ejemploIn the example

class C<T>
{
    protected T x;
}

class D<T>: C<T>
{
    static void F() {
        D<T> dt = new D<T>();
        D<int> di = new D<int>();
        D<string> ds = new D<string>();
        dt.x = default(T);
        di.x = 123;
        ds.x = "test";
    }
}

las tres asignaciones a x se permiten porque tienen lugar a través de las instancias de tipos de clase construidos a partir del tipo genérico.the three assignments to x are permitted because they all take place through instances of class types constructed from the generic type.

Restricciones de accesibilidadAccessibility constraints

Varias construcciones del lenguaje C# requieren un tipo sea al menos tan accesibles como miembro u otro tipo.Several constructs in the C# language require a type to be at least as accessible as a member or another type. Un tipo T se dice que ser al menos tan accesibles como un miembro o tipo M si el dominio de accesibilidad de T es un superconjunto del dominio de accesibilidad de M.A type T is said to be at least as accessible as a member or type M if the accessibility domain of T is a superset of the accessibility domain of M. En otras palabras, T es al menos tan accesibles como M si T es accesible en todos los contextos en los que M es accesible.In other words, T is at least as accessible as M if T is accessible in all contexts in which M is accessible.

Existen las siguientes restricciones de accesibilidad:The following accessibility constraints exist:

  • La clase base directa de un tipo de clase debe ser al menos igual de accesible que el propio tipo de clase.The direct base class of a class type must be at least as accessible as the class type itself.
  • Las interfaces base explícitas de un tipo de interfaz deben ser al menos igual de accesibles que el propio tipo de interfaz.The explicit base interfaces of an interface type must be at least as accessible as the interface type itself.
  • El tipo de valor devuelto y los tipos de parámetros de un tipo de delegado deben ser al menos igual de accesibles que el propio tipo de delegado.The return type and parameter types of a delegate type must be at least as accessible as the delegate type itself.
  • El tipo de una constante debe ser al menos igual de accesible que la propia constante.The type of a constant must be at least as accessible as the constant itself.
  • El tipo de un campo debe ser al menos igual de accesible que el propio campo.The type of a field must be at least as accessible as the field itself.
  • El tipo de valor devuelto y los tipos de parámetros de un método deben ser al menos igual de accesibles que el propio método.The return type and parameter types of a method must be at least as accessible as the method itself.
  • El tipo de una propiedad debe ser al menos igual de accesible que la misma propiedad.The type of a property must be at least as accessible as the property itself.
  • El tipo de un evento debe ser al menos igual de accesible que el propio evento.The type of an event must be at least as accessible as the event itself.
  • Los tipos de parámetro y el tipo de un indexador deben ser al menos igual de accesibles que el propio indexador.The type and parameter types of an indexer must be at least as accessible as the indexer itself.
  • El tipo de valor devuelto y los tipos de parámetro de un operador deben ser al menos igual de accesibles que el propio operador.The return type and parameter types of an operator must be at least as accessible as the operator itself.
  • Los tipos de parámetros de un constructor de instancia deben ser al menos tan accesibles como el propio constructor de instancia.The parameter types of an instance constructor must be at least as accessible as the instance constructor itself.

En el ejemploIn the example

class A {...}

public class B: A {...}

el B clase produce un error en tiempo de compilación porque A no es al menos tan accesibles como B.the B class results in a compile-time error because A is not at least as accessible as B.

Del mismo modo, en el ejemploLikewise, in the example

class A {...}

public class B
{
    A F() {...}

    internal A G() {...}

    public A H() {...}
}

el H método B da como resultado un error en tiempo de compilación porque el tipo de devolución A no es al menos tan accesibles como el método.the H method in B results in a compile-time error because the return type A is not at least as accessible as the method.

Firmas y sobrecargaSignatures and overloading

Los métodos, constructores de instancias, indizadores y los operadores se caracterizan por su firmas:Methods, instance constructors, indexers, and operators are characterized by their signatures:

  • La firma de un método se compone del nombre del método, el número de parámetros de tipo y el tipo y la categoría (valor, referencia o salida) de cada uno de sus parámetros formales, considerados en el orden de izquierda a derecha.The signature of a method consists of the name of the method, the number of type parameters and the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. Para estos fines, se identifica cualquier parámetro de tipo del método que se produce en el tipo de un parámetro formal no por su nombre, pero por su posición ordinal en la lista de argumentos de tipo del método.For these purposes, any type parameter of the method that occurs in the type of a formal parameter is identified not by its name, but by its ordinal position in the type argument list of the method. En concreto la firma de un método no incluye el tipo de valor devuelto, el params modificador que se puede especificar para el parámetro de la derecha, ni las restricciones de parámetro de tipo opcional.The signature of a method specifically does not include the return type, the params modifier that may be specified for the right-most parameter, nor the optional type parameter constraints.
  • La firma de un constructor de instancia se compone del tipo y la categoría (valor, referencia o salida) de cada uno de sus parámetros formales, considerados en el orden de izquierda a derecha.The signature of an instance constructor consists of the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. No incluye la firma de un constructor de instancia en concreto la params modificador que se puede especificar para el parámetro de la derecha.The signature of an instance constructor specifically does not include the params modifier that may be specified for the right-most parameter.
  • La firma de un indizador se compone del tipo de cada uno de sus parámetros formales, considerados en el orden de izquierda a derecha.The signature of an indexer consists of the type of each of its formal parameters, considered in the order left to right. La firma de un indizador específicamente no incluye el tipo de elemento, ni incluye el params modificador que se puede especificar para el parámetro de la derecha.The signature of an indexer specifically does not include the element type, nor does it include the params modifier that may be specified for the right-most parameter.
  • La firma de un operador se compone del nombre del operador y el tipo de cada uno de sus parámetros formales, considerados en el orden de izquierda a derecha.The signature of an operator consists of the name of the operator and the type of each of its formal parameters, considered in the order left to right. En concreto, la firma de un operador no incluye el tipo de resultado.The signature of an operator specifically does not include the result type.

Las firmas son el mecanismo que permite sobrecarga de los miembros de clases, structs e interfaces:Signatures are the enabling mechanism for overloading of members in classes, structs, and interfaces:

  • La sobrecarga de métodos permite que una clase, estructura o interfaz declare varios métodos con el mismo nombre, siempre que sus firmas sean únicas dentro de esa clase, estructura o interfaz.Overloading of methods permits a class, struct, or interface to declare multiple methods with the same name, provided their signatures are unique within that class, struct, or interface.
  • La sobrecarga de constructores de instancia permite que una clase o struct declare varios constructores de instancia, siempre que sus firmas sean únicas dentro de esa clase o struct.Overloading of instance constructors permits a class or struct to declare multiple instance constructors, provided their signatures are unique within that class or struct.
  • La sobrecarga de indizadores permite que una clase, estructura o interfaz declare varios indizadores, siempre que sus firmas sean únicas dentro de esa clase, estructura o interfaz.Overloading of indexers permits a class, struct, or interface to declare multiple indexers, provided their signatures are unique within that class, struct, or interface.
  • La sobrecarga de operadores permite que una clase o struct declare varios operadores con el mismo nombre, siempre que sus firmas sean únicos dentro de esa clase o struct.Overloading of operators permits a class or struct to declare multiple operators with the same name, provided their signatures are unique within that class or struct.

Aunque out y ref modificadores de parámetro se consideran parte de una firma, los miembros declarados en un tipo único no pueden diferenciarse únicamente mediante en firma ref y out.Although out and ref parameter modifiers are considered part of a signature, members declared in a single type cannot differ in signature solely by ref and out. Se produce un error de tiempo de compilación si se declaran dos miembros en el mismo tipo con firmas que sería el misma si todos los parámetros de ambos métodos con out modificadores cambiaron a ref modificadores.A compile-time error occurs if two members are declared in the same type with signatures that would be the same if all parameters in both methods with out modifiers were changed to ref modifiers. Para otros fines de coincidencia de firma (por ejemplo, ocultar o reemplazar) ref y out se consideran parte de la firma y no coinciden entre sí.For other purposes of signature matching (e.g., hiding or overriding), ref and out are considered part of the signature and do not match each other. (Esta restricción es permitirle C# programas que se deben traducir fácilmente para ejecutarse en el Common Language Infrastructure (CLI), que no proporciona una manera de definir métodos que difieran únicamente en ref y out.)(This restriction is to allow C#  programs to be easily translated to run on the Common Language Infrastructure (CLI), which does not provide a way to define methods that differ solely in ref and out.)

Para los fines de firmas, los tipos de object y dynamic se consideran iguales.For the purposes of signatures, the types object and dynamic are considered the same. Los miembros declarados en un tipo único pueden, por tanto, no difieren en firma únicamente mediante object y dynamic.Members declared in a single type can therefore not differ in signature solely by object and dynamic.

El ejemplo siguiente muestra un conjunto de declaraciones de método sobrecargado, junto con sus firmas.The following example shows a set of overloaded method declarations along with their signatures.

interface ITest
{
    void F();                        // F()

    void F(int x);                   // F(int)

    void F(ref int x);               // F(ref int)

    void F(out int x);               // F(out int)      error

    void F(int x, int y);            // F(int, int)

    int F(string s);                 // F(string)

    int F(int x);                    // F(int)          error

    void F(string[] a);              // F(string[])

    void F(params string[] a);       // F(string[])     error
}

Tenga en cuenta que cualquier ref y out modificadores de parámetro (parámetros del método) forman parte de una firma.Note that any ref and out parameter modifiers (Method parameters) are part of a signature. Por lo tanto, F(int) y F(ref int) son firmas únicas.Thus, F(int) and F(ref int) are unique signatures. Sin embargo, F(ref int) y F(out int) no se pueden declarar dentro de la misma interfaz porque sus firmas se diferencian solamente por ref y out.However, F(ref int) and F(out int) cannot be declared within the same interface because their signatures differ solely by ref and out. Además, tenga en cuenta que el tipo de devolución y el params modificador no forman parte de una firma, por lo que no es posible sobrecargar solamente basado en el tipo de valor devuelto o en la inclusión o exclusión de la params modificador.Also, note that the return type and the params modifier are not part of a signature, so it is not possible to overload solely based on return type or on the inclusion or exclusion of the params modifier. Como tal, las declaraciones de los métodos F(int) y F(params string[]) anteriormente identificadas producen un error en tiempo de compilación.As such, the declarations of the methods F(int) and F(params string[]) identified above result in a compile-time error.

ÁmbitosScopes

El ámbito de un nombre es la región de texto dentro del cual es posible hacer referencia a la entidad declarada por el nombre sin la calificación del nombre del programa.The scope of a name is the region of program text within which it is possible to refer to the entity declared by the name without qualification of the name. Los ámbitos pueden ser anidada, y un ámbito interno puede volver a declarar el significado de un nombre de un ámbito externo (no, sin embargo, se quitará la restricción impuesta por declaraciones que dentro de un bloque anidado no es es posible declarar una variable local con el mismo nombre que una variable local en un bloque de inclusión).Scopes can be nested, and an inner scope may redeclare the meaning of a name from an outer scope (this does not, however, remove the restriction imposed by Declarations that within a nested block it is not possible to declare a local variable with the same name as a local variable in an enclosing block). El nombre del ámbito externo, a continuación, se dice que oculto en la región del programa de texto cubierto por el ámbito interno, y acceso para el nombre exterior solo es posible calificando el nombre.The name from the outer scope is then said to be hidden in the region of program text covered by the inner scope, and access to the outer name is only possible by qualifying the name.

  • El ámbito de un miembro del espacio de nombres declarado por una namespace_member_declaration (Namespace miembros) con ningún envolvente namespace_declaration es todo el programa texto.The scope of a namespace member declared by a namespace_member_declaration (Namespace members) with no enclosing namespace_declaration is the entire program text.
  • El ámbito de un miembro del espacio de nombres declarado por una namespace_member_declaration dentro de un namespace_declaration cuyo nombre completo es N es el namespace_body de cada namespace_declaration cuyo nombre completo es N o empieza por N, seguido de un período.The scope of a namespace member declared by a namespace_member_declaration within a namespace_declaration whose fully qualified name is N is the namespace_body of every namespace_declaration whose fully qualified name is N or starts with N, followed by a period.
  • El ámbito del nombre definido por un extern_alias_directive se extiende a través de la using_directives, global_attributes y namespace_member_ declaracións de su cuerpo contenedor inmediato de espacio de nombres o la unidad de compilación.The scope of name defined by an extern_alias_directive extends over the using_directives, global_attributes and namespace_member_declarations of its immediately containing compilation unit or namespace body. Un extern_alias_directive no contribuye con ningún miembro nuevo al espacio de declaración subyacente.An extern_alias_directive does not contribute any new members to the underlying declaration space. En otras palabras, un extern_alias_directive no es transitiva, pero, en su lugar, sólo afecta a la compilación unidad o el espacio de nombres de cuerpo en el que se produce.In other words, an extern_alias_directive is not transitive, but, rather, affects only the compilation unit or namespace body in which it occurs.
  • El ámbito de un nombre definido o importado por un using_directive (directivas Using) se extiende a través de la namespace_member_declarations de la compilation_unit o namespace_body en el que el using_directive se produce.The scope of a name defined or imported by a using_directive (Using directives) extends over the namespace_member_declarations of the compilation_unit or namespace_body in which the using_directive occurs. Un using_directive puede poner a cero o más nombres de espacio de nombres, tipo o miembro disposición dentro de un determinado compilation_unit o namespace_body, pero no lo hace contribuir con los nuevos miembros al espacio de declaración subyacente.A using_directive may make zero or more namespace, type or member names available within a particular compilation_unit or namespace_body, but does not contribute any new members to the underlying declaration space. En otras palabras, un using_directive no es transitiva, sino más bien afecta solo a la compilation_unit o namespace_body en el que se produce.In other words, a using_directive is not transitive but rather affects only the compilation_unit or namespace_body in which it occurs.
  • El ámbito de un parámetro de tipo declarado por una type_parameter_list en un class_declaration (declaraciones de clase) es el class_base, type_parameter_constraints_clauses, y class_body eso class_declaration.The scope of a type parameter declared by a type_parameter_list on a class_declaration (Class declarations) is the class_base, type_parameter_constraints_clauses, and class_body of that class_declaration.
  • El ámbito de un parámetro de tipo declarado por una type_parameter_list en un struct_declaration (declaraciones de estructura) es el struct_interfaces , type_parameter_constraints_clauses, y struct_body eso struct_declaration.The scope of a type parameter declared by a type_parameter_list on a struct_declaration (Struct declarations) is the struct_interfaces, type_parameter_constraints_clauses, and struct_body of that struct_declaration.
  • El ámbito de un parámetro de tipo declarado por una type_parameter_list en un interface_declaration (declaraciones de interfaz) es el interface_base , type_parameter_constraints_clauses, y interface_body eso interface_declaration.The scope of a type parameter declared by a type_parameter_list on an interface_declaration (Interface declarations) is the interface_base, type_parameter_constraints_clauses, and interface_body of that interface_declaration.
  • El ámbito de un parámetro de tipo declarado por una type_parameter_list en un delegate_declaration (declaraciones de delegado) es el return_type, formal_parameter_list, y type_parameter_constraints_clauses eso delegate_declaration.The scope of a type parameter declared by a type_parameter_list on a delegate_declaration (Delegate declarations) is the return_type, formal_parameter_list, and type_parameter_constraints_clauses of that delegate_declaration.
  • El ámbito de un miembro declarado por una class_member_declaration (clase cuerpo) es el class_body en que se produce la declaración.The scope of a member declared by a class_member_declaration (Class body) is the class_body in which the declaration occurs. Además, el ámbito de un miembro de clase se extiende a la class_body de las clases derivadas que se incluyen en el dominio de accesibilidad (dominios de accesibilidad) del miembro.In addition, the scope of a class member extends to the class_body of those derived classes that are included in the accessibility domain (Accessibility domains) of the member.
  • El ámbito de un miembro declarado por una struct_member_declaration (los miembros de Struct) es el struct_body en que se produce la declaración.The scope of a member declared by a struct_member_declaration (Struct members) is the struct_body in which the declaration occurs.
  • El ámbito de un miembro declarado por una enum_member_declaration (miembros de enumeración) es el enum_body en que se produce la declaración.The scope of a member declared by an enum_member_declaration (Enum members) is the enum_body in which the declaration occurs.
  • El ámbito de un parámetro declarado en un method_declaration (métodos) es el cuerpoMétodo eso method_declaration.The scope of a parameter declared in a method_declaration (Methods) is the method_body of that method_declaration.
  • El ámbito de un parámetro declarado en una indexer_declaration (indizadores) es el accessor_declarations eso indexer_declaration.The scope of a parameter declared in an indexer_declaration (Indexers) is the accessor_declarations of that indexer_declaration.
  • El ámbito de un parámetro declarado en una operator_declaration (operadores) es el bloque eso operator_declaration.The scope of a parameter declared in an operator_declaration (Operators) is the block of that operator_declaration.
  • El ámbito de un parámetro declarado en un constructor_declaration (constructores de instancias) es el constructor_initializer y bloque eso constructor_declaration.The scope of a parameter declared in a constructor_declaration (Instance constructors) is the constructor_initializer and block of that constructor_declaration.
  • El ámbito de un parámetro declarado en un lambda_expression (expresiones de función anónima) es el anonymous_function_body eso lambda_ expresiónThe scope of a parameter declared in a lambda_expression (Anonymous function expressions) is the anonymous_function_body of that lambda_expression
  • El ámbito de un parámetro declarado en una anonymous_method_expression (expresiones de función anónima) es el bloque eso anonymous_method _expression.The scope of a parameter declared in an anonymous_method_expression (Anonymous function expressions) is the block of that anonymous_method_expression.
  • El ámbito de una etiqueta declarada en una labeled_statement (con la etiqueta instrucciones) es el bloque en que se produce la declaración.The scope of a label declared in a labeled_statement (Labeled statements) is the block in which the declaration occurs.
  • El ámbito de una variable local declarada en un local_variable_declaration (declaraciones de variable Local) es el bloque en que se produce la declaración.The scope of a local variable declared in a local_variable_declaration (Local variable declarations) is the block in which the declaration occurs.
  • El ámbito de una variable local declarada en un switch_block de un switch instrucción (la instrucción switch) es el switch_block.The scope of a local variable declared in a switch_block of a switch statement (The switch statement) is the switch_block.
  • El ámbito de una variable local declarada en un for_initializer de un for instrucción (la instrucción for) es el for_initializer, el for_condition, for_iteratory el objeto contenido instrucción de la for instrucción.The scope of a local variable declared in a for_initializer of a for statement (The for statement) is the for_initializer, the for_condition, the for_iterator, and the contained statement of the for statement.
  • El ámbito de una constante local declarada en un local_constant_declaration (declaraciones de constante Local) es el bloque en que se produce la declaración.The scope of a local constant declared in a local_constant_declaration (Local constant declarations) is the block in which the declaration occurs. Es un error en tiempo de compilación para hacer referencia a una constante local en una posición textual que precede a su constant_declarator.It is a compile-time error to refer to a local constant in a textual position that precedes its constant_declarator.
  • El ámbito de una variable declarada como parte de un foreach_statement, using_statement, lock_statement o expresión_de_consulta es determinado por la expansión de la construcción.The scope of a variable declared as part of a foreach_statement, using_statement, lock_statement or query_expression is determined by the expansion of the given construct.

Dentro del ámbito de un miembro del espacio de nombres, clase, estructura o enumeración es posible hacer referencia al miembro en una posición textual que precede a la declaración del miembro.Within the scope of a namespace, class, struct, or enumeration member it is possible to refer to the member in a textual position that precedes the declaration of the member. Por ejemploFor example

class A
{
    void F() {
        i = 1;
    }

    int i = 0;
}

En este caso, es válido para F para hacer referencia a i antes de declararla.Here, it is valid for F to refer to i before it is declared.

Dentro del ámbito de una variable local, es un error en tiempo de compilación para hacer referencia a la variable local en una posición textual que precede a la local_variable_declarator de la variable local.Within the scope of a local variable, it is a compile-time error to refer to the local variable in a textual position that precedes the local_variable_declarator of the local variable. Por ejemploFor example

class A
{
    int i = 0;

    void F() {
        i = 1;                  // Error, use precedes declaration
        int i;
        i = 2;
    }

    void G() {
        int j = (j = 1);        // Valid
    }

    void H() {
        int a = 1, b = ++a;    // Valid
    }
}

En el F método anterior, la primera asignación i específicamente no hace referencia al campo declarado en el ámbito externo.In the F method above, the first assignment to i specifically does not refer to the field declared in the outer scope. En su lugar, hace referencia a la variable local y produce un error en tiempo de compilación porque le precede en la declaración de la variable.Rather, it refers to the local variable and it results in a compile-time error because it textually precedes the declaration of the variable. En el G método, el uso de j en el inicializador de la declaración de j es válido porque no precede el local_variable_declarator.In the G method, the use of j in the initializer for the declaration of j is valid because the use does not precede the local_variable_declarator. En el H método, un posterior local_variable_declarator correctamente hace referencia a una variable local declarada en una sesión local_variable_declarator dentro del mismo local_variable_declaration.In the H method, a subsequent local_variable_declarator correctly refers to a local variable declared in an earlier local_variable_declarator within the same local_variable_declaration.

Las reglas de ámbito para las variables locales están diseñadas para garantizar que el significado de un nombre usado en un contexto de expresión siempre es el mismo dentro de un bloque.The scoping rules for local variables are designed to guarantee that the meaning of a name used in an expression context is always the same within a block. Si fuera del ámbito de una variable local ampliar solo de su declaración hasta el final del bloque, a continuación, en el ejemplo anterior, la primera asignación asignará a la variable de instancia y la segunda asignación asignaría a la variable local, es posible errores de tiempo de compilación si más adelante se reorganicen fueron de las instrucciones del bloque.If the scope of a local variable were to extend only from its declaration to the end of the block, then in the example above, the first assignment would assign to the instance variable and the second assignment would assign to the local variable, possibly leading to compile-time errors if the statements of the block were later to be rearranged.

El significado de un nombre dentro de un bloque puede diferir según el contexto en el que se usa el nombre.The meaning of a name within a block may differ based on the context in which the name is used. En el ejemploIn the example

using System;

class A {}

class Test
{
    static void Main() {
        string A = "hello, world";
        string s = A;                            // expression context

        Type t = typeof(A);                      // type context

        Console.WriteLine(s);                    // writes "hello, world"
        Console.WriteLine(t);                    // writes "A"
    }
}

el nombre A se usa en un contexto de expresión para hacer referencia a la variable local A y en un contexto de tipo para hacer referencia a la clase A.the name A is used in an expression context to refer to the local variable A and in a type context to refer to the class A.

Ocultación de nombresName hiding

El ámbito de una entidad normalmente abarca más texto del programa que el espacio de declaración de la entidad.The scope of an entity typically encompasses more program text than the declaration space of the entity. En concreto, el ámbito de una entidad puede incluir declaraciones que introducen nuevos espacios de declaración que contiene las entidades del mismo nombre.In particular, the scope of an entity may include declarations that introduce new declaration spaces containing entities of the same name. Estas declaraciones hacen que la entidad original para convertirse en oculto.Such declarations cause the original entity to become hidden. Por el contrario, se dice que una entidad se visible cuando no está oculto.Conversely, an entity is said to be visible when it is not hidden.

Ocultación de nombres se produce cuando los ámbitos se superponen a través de anidamiento y cuando se superponen a través de herencia.Name hiding occurs when scopes overlap through nesting and when scopes overlap through inheritance. Las características de los dos tipos de ocultación se describen en las secciones siguientes.The characteristics of the two types of hiding are described in the following sections.

Ocultar mediante anidaciónHiding through nesting

A través de anidamiento de la ocultación de nombres pueden producir como resultado de anidamiento de los espacios de nombres o tipos dentro de espacios de nombres, como resultado de anidamiento de tipos dentro de clases o structs y el resultado de parámetro y declaraciones de variable local.Name hiding through nesting can occur as a result of nesting namespaces or types within namespaces, as a result of nesting types within classes or structs, and as a result of parameter and local variable declarations.

En el ejemploIn the example

class A
{
    int i = 0;

    void F() {
        int i = 1;
    }

    void G() {
        i = 1;
    }
}

dentro de la F método, la variable de instancia i está oculto por la variable local i, pero dentro del G método, i todavía hace referencia a la variable de instancia.within the F method, the instance variable i is hidden by the local variable i, but within the G method, i still refers to the instance variable.

Cuando un nombre en un ámbito interno oculta un nombre en un ámbito externo, oculta todas las apariciones sobrecargadas de ese nombre.When a name in an inner scope hides a name in an outer scope, it hides all overloaded occurrences of that name. En el ejemploIn the example

class Outer
{
    static void F(int i) {}

    static void F(string s) {}

    class Inner
    {
        void G() {
            F(1);              // Invokes Outer.Inner.F
            F("Hello");        // Error
        }

        static void F(long l) {}
    }
}

la llamada F(1) invoca el F declarado en Inner porque todas las apariciones externas de F oculta la declaración interna.the call F(1) invokes the F declared in Inner because all outer occurrences of F are hidden by the inner declaration. Para la misma razón, la llamada F("Hello") da como resultado un error en tiempo de compilación.For the same reason, the call F("Hello") results in a compile-time error.

Ocultar mediante herenciaHiding through inheritance

A través de la herencia de la ocultación de nombres se produce cuando las clases o structs declarar nombres que se han heredado de clases base.Name hiding through inheritance occurs when classes or structs redeclare names that were inherited from base classes. Este tipo de ocultación de nombres toma una de las siguientes formas:This type of name hiding takes one of the following forms:

  • Constante, campo, propiedad, evento o tipo introducido en una clase o struct oculta a todos los miembros de clase base con el mismo nombre.A constant, field, property, event, or type introduced in a class or struct hides all base class members with the same name.
  • Un método introducido en una clase o struct oculta todos los miembros de clase base que no son de método con el mismo nombre y todos los métodos de clase base con la misma firma (nombre del método y el número de parámetros, modificadores y tipos).A method introduced in a class or struct hides all non-method base class members with the same name, and all base class methods with the same signature (method name and parameter count, modifiers, and types).
  • Un indizador introducido en una clase o struct oculta todos los indizadores de clase base con la misma firma (número de parámetros y tipos).An indexer introduced in a class or struct hides all base class indexers with the same signature (parameter count and types).

Las reglas que rigen las declaraciones de operadores (operadores) hacen que sea imposible que una clase derivada declarar un operador con la misma firma que un operador en una clase base.The rules governing operator declarations (Operators) make it impossible for a derived class to declare an operator with the same signature as an operator in a base class. Por lo tanto, los operadores nunca ocultan entre sí.Thus, operators never hide one another.

Al contrario de ocultar un nombre de un ámbito externo, un nombre accesible desde un ámbito heredado se ocultan, una advertencia que se notificarán.Contrary to hiding a name from an outer scope, hiding an accessible name from an inherited scope causes a warning to be reported. En el ejemploIn the example

class Base
{
    public void F() {}
}

class Derived: Base
{
    public void F() {}        // Warning, hiding an inherited name
}

la declaración de F en Derived , notificará un mensaje de advertencia.the declaration of F in Derived causes a warning to be reported. Ocultar un nombre heredado no es específicamente un error, puesto que esto impediría la evolución independiente de las clases base.Hiding an inherited name is specifically not an error, since that would preclude separate evolution of base classes. Por ejemplo, la situación anterior podría haber producido porque una versión posterior de Base introdujo un F método que no estaba presente en una versión anterior de la clase.For example, the above situation might have come about because a later version of Base introduced an F method that wasn't present in an earlier version of the class. Si la situación anterior que hubiera un error, a continuación, cualquier cambio realizado en una clase base en una biblioteca de clases por separado con control de versiones podría convertir las clases derivadas para dejar de ser válido.Had the above situation been an error, then any change made to a base class in a separately versioned class library could potentially cause derived classes to become invalid.

La advertencia causada por la ocultación de un nombre heredado puede eliminarse mediante el uso de la new modificador:The warning caused by hiding an inherited name can be eliminated through use of the new modifier:

class Base
{
    public void F() {}
}

class Derived: Base
{
    new public void F() {}
}

El new modificador indica que el F en Derived es "new", y que realmente está pensado para ocultar el miembro heredado.The new modifier indicates that the F in Derived is "new", and that it is indeed intended to hide the inherited member.

Una declaración de un nuevo miembro oculta a un miembro heredado solo dentro del ámbito del nuevo miembro.A declaration of a new member hides an inherited member only within the scope of the new member.

class Base
{
    public static void F() {}
}

class Derived: Base
{
    new private static void F() {}    // Hides Base.F in Derived only
}

class MoreDerived: Derived
{
    static void G() { F(); }          // Invokes Base.F
}

En el ejemplo anterior, la declaración de F en Derived oculta la F que heredó Base, pero como el nuevo F en Derived tiene acceso privado, su ámbito no se extiende a MoreDerived .In the example above, the declaration of F in Derived hides the F that was inherited from Base, but since the new F in Derived has private access, its scope does not extend to MoreDerived. Por lo tanto, la llamada F() en MoreDerived.G es válido y que invocará Base.F.Thus, the call F() in MoreDerived.G is valid and will invoke Base.F.

Namespace y nombres de tipoNamespace and type names

Algunos contextos de un C# programa requiere una namespace_name o un type_name que se especifique.Several contexts in a C# program require a namespace_name or a type_name to be specified.

namespace_name
    : namespace_or_type_name
    ;

type_name
    : namespace_or_type_name
    ;

namespace_or_type_name
    : identifier type_argument_list?
    | namespace_or_type_name '.' identifier type_argument_list?
    | qualified_alias_member
    ;

Un namespace_name es un namespace_or_type_name que hace referencia a un espacio de nombres.A namespace_name is a namespace_or_type_name that refers to a namespace. Seguir resolución tal y como se describe a continuación, el namespace_or_type_name de un namespace_name debe hacer referencia a un espacio de nombres o de lo contrario se produce un error en tiempo de compilación.Following resolution as described below, the namespace_or_type_name of a namespace_name must refer to a namespace, or otherwise a compile-time error occurs. Ningún argumento de tipo (argumentos de tipo) pueden estar presentes en un namespace_name (solo tipos pueden tener argumentos de tipo).No type arguments (Type arguments) can be present in a namespace_name (only types can have type arguments).

Un type_name es un namespace_or_type_name que hace referencia a un tipo.A type_name is a namespace_or_type_name that refers to a type. Seguir resolución tal y como se describe a continuación, el namespace_or_type_name de un type_name debe hacer referencia a un tipo, o en caso contrario, se produce un error en tiempo de compilación.Following resolution as described below, the namespace_or_type_name of a type_name must refer to a type, or otherwise a compile-time error occurs.

Si el namespace_or_type_name es un completo-alias-miembro de su significado como se describe en calificadores de alias Namespace.If the namespace_or_type_name is a qualified-alias-member its meaning is as described in Namespace alias qualifiers. En caso contrario, un namespace_or_type_name tiene uno de estos cuatro formatos:Otherwise, a namespace_or_type_name has one of four forms:

  • I
  • I<A1, ..., Ak>
  • N.I
  • N.I<A1, ..., Ak>

donde I es un identificador único, N es un namespace_or_type_name y <A1, ..., Ak> es una función opcional type_argument_list.where I is a single identifier, N is a namespace_or_type_name and <A1, ..., Ak> is an optional type_argument_list. Cuando no hay ninguna type_argument_list está especificado, considere la posibilidad de k sea cero.When no type_argument_list is specified, consider k to be zero.

El significado de un namespace_or_type_name se determina como sigue:The meaning of a namespace_or_type_name is determined as follows:

  • Si el namespace_or_type_name tiene el formato I o tiene el formato I<A1, ..., Ak>:If the namespace_or_type_name is of the form I or of the form I<A1, ..., Ak>:
    • Si K es cero y el namespace_or_type_name aparece dentro de una declaración de método genérico (métodos) y si dicha declaración incluye un parámetro de tipo (tipo parámetros) con el nombre I, el namespace_or_type_name hace referencia a ese parámetro de tipo.If K is zero and the namespace_or_type_name appears within a generic method declaration (Methods) and if that declaration includes a type parameter (Type parameters) with name I, then the namespace_or_type_name refers to that type parameter.
    • De lo contrario, si la namespace_or_type_name aparece dentro de una declaración de tipo y, después, para cada tipo de instancia T (el tipo de instancia), empezando por el tipo de instancia de ese tipo declaración y continuando con el tipo de instancia de cada declaración de clase o estructura envolvente (si existe):Otherwise, if the namespace_or_type_name appears within a type declaration, then for each instance type T (The instance type), starting with the instance type of that type declaration and continuing with the instance type of each enclosing class or struct declaration (if any):
      • Si K es cero y la declaración de T incluye un parámetro de tipo con nombre I, el namespace_or_type_name hace referencia a ese parámetro de tipo.If K is zero and the declaration of T includes a type parameter with name I, then the namespace_or_type_name refers to that type parameter.
      • De lo contrario, si la namespace_or_type_name aparece dentro del cuerpo de la declaración de tipos, y T o cualquiera de sus tipos base contiene un tipo accesible anidado con el nombre I y K  parámetros de tipo, el namespace_or_type_name hace referencia a ese tipo construido con los argumentos de tipo especificado.Otherwise, if the namespace_or_type_name appears within the body of the type declaration, and T or any of its base types contain a nested accessible type having name I and K type parameters, then the namespace_or_type_name refers to that type constructed with the given type arguments. Si hay más de uno de estos tipos, se selecciona el tipo declarado dentro del tipo más derivado.If there is more than one such type, the type declared within the more derived type is selected. Tenga en cuenta que los miembros sin tipo (constantes, campos, métodos, propiedades, indizadores, operadores, constructores de instancias, destructores y constructores estáticos) y los miembros de tipo con un número diferente de parámetros de tipo se omiten al determinar el significado de la namespace_or_type_name.Note that non-type members (constants, fields, methods, properties, indexers, operators, instance constructors, destructors, and static constructors) and type members with a different number of type parameters are ignored when determining the meaning of the namespace_or_type_name.
    • Si los pasos anteriores eran incorrectas, a continuación, para cada espacio de nombres N, empezando por el espacio de nombres en el que el namespace_or_type_name se produce, continúe con cada espacio de nombres envolvente (si existe) y terminando con el espacio de nombres global, se evalúan los pasos siguientes hasta que se encuentra una entidad:If the previous steps were unsuccessful then, for each namespace N, starting with the namespace in which the namespace_or_type_name occurs, continuing with each enclosing namespace (if any), and ending with the global namespace, the following steps are evaluated until an entity is located:
      • Si K es cero y I es el nombre de un espacio de nombres en N, a continuación:If K is zero and I is the name of a namespace in N, then:
        • Si la ubicación donde el namespace_or_type_name se produce entre una declaración de espacio de nombres para N y la declaración de espacio de nombres contiene un extern_alias_directive o using_alias_directive que asocia el nombre I con un espacio de nombres o tipo, el namespace_or_type_name es ambiguo y se produce un error en tiempo de compilación.If the location where the namespace_or_type_name occurs is enclosed by a namespace declaration for N and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with a namespace or type, then the namespace_or_type_name is ambiguous and a compile-time error occurs.
        • En caso contrario, el namespace_or_type_name hace referencia al espacio de nombres denominado I en N.Otherwise, the namespace_or_type_name refers to the namespace named I in N.
      • De lo contrario, si N contiene un tipo accesible con nombre I y K  parámetros de tipo:Otherwise, if N contains an accessible type having name I and K type parameters, then:
        • Si K es cero y la ubicación donde el namespace_or_type_name se produce entre una declaración de espacio de nombres para N y la declaración de espacio de nombres contiene un extern_alias_directive o using_alias_directive que asocia el nombre I con un espacio de nombres o tipo, el namespace_or_type_name es ambiguo y un tiempo de compilación se produce un error.If K is zero and the location where the namespace_or_type_name occurs is enclosed by a namespace declaration for N and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with a namespace or type, then the namespace_or_type_name is ambiguous and a compile-time error occurs.
        • En caso contrario, el namespace_or_type_name hace referencia al tipo construido con los argumentos de tipo especificado.Otherwise, the namespace_or_type_name refers to the type constructed with the given type arguments.
      • De lo contrario, si la ubicación donde el namespace_or_type_name se produce entre una declaración de espacio de nombres para N:Otherwise, if the location where the namespace_or_type_name occurs is enclosed by a namespace declaration for N:
        • Si K es cero y la declaración de espacio de nombres contiene un extern_alias_directive o using_alias_directive que asocia el nombre I con un espacio de nombres importado o tipo, el namespace_or_type_name hace referencia a dicho espacio de nombres o tipo.If K is zero and the namespace declaration contains an extern_alias_directive or using_alias_directive that associates the name I with an imported namespace or type, then the namespace_or_type_name refers to that namespace or type.
        • En caso contrario, si las declaraciones de espacios de nombres y el tipo importan por el using_namespace_directives y using_alias_directives de la declaración de espacio de nombres contiene exactamente un tipo accesible con el nombre I y K  parámetros de tipo, el namespace_or_type_name hace referencia a ese tipo construido con los argumentos de tipo especificado.Otherwise, if the namespaces and type declarations imported by the using_namespace_directives and using_alias_directives of the namespace declaration contain exactly one accessible type having name I and K type parameters, then the namespace_or_type_name refers to that type constructed with the given type arguments.
        • En caso contrario, si las declaraciones de espacios de nombres y el tipo importan por el using_namespace_directives y using_alias_directives de la declaración de espacio de nombres contiene más de un tipo accesible con el nombre I y K  parámetros de tipo, el namespace_or_type_name es ambiguo y se produce un error.Otherwise, if the namespaces and type declarations imported by the using_namespace_directives and using_alias_directives of the namespace declaration contain more than one accessible type having name I and K type parameters, then the namespace_or_type_name is ambiguous and an error occurs.
    • En caso contrario, el namespace_or_type_name es no definido y se produce un error de tiempo de compilación.Otherwise, the namespace_or_type_name is undefined and a compile-time error occurs.
  • En caso contrario, el namespace_or_type_name tiene el formato N.I o tiene el formato N.I<A1, ..., Ak>.Otherwise, the namespace_or_type_name is of the form N.I or of the form N.I<A1, ..., Ak>. N en primer lugar se resuelve como un namespace_or_type_name.N is first resolved as a namespace_or_type_name. Si la resolución de N no es correcta, se produce un error de tiempo de compilación.If the resolution of N is not successful, a compile-time error occurs. En caso contrario, N.I o N.I<A1, ..., Ak> se resuelve como sigue:Otherwise, N.I or N.I<A1, ..., Ak> is resolved as follows:
    • Si K es cero y N hace referencia a un espacio de nombres y N contiene un espacio de nombres anidado con nombre I, el namespace_or_type_name hace referencia a ese espacio de nombres anidado.If K is zero and N refers to a namespace and N contains a nested namespace with name I, then the namespace_or_type_name refers to that nested namespace.
    • De lo contrario, si N hace referencia a un espacio de nombres y N contiene un tipo accesible con nombre I y K  parámetros de tipo, el namespace_or_type_name hace referencia en ese tipo construido con los argumentos de tipo especificado.Otherwise, if N refers to a namespace and N contains an accessible type having name I and K type parameters, then the namespace_or_type_name refers to that type constructed with the given type arguments.
    • De lo contrario, si N hace referencia a un tipo de clase o struct (posiblemente construido) y N o cualquiera de sus clases base contiene un tipo accesible anidado con el nombre I y K  escriba los parámetros y, a continuación, el namespace_or_type_name hace referencia a ese tipo construido con los argumentos de tipo especificado.Otherwise, if N refers to a (possibly constructed) class or struct type and N or any of its base classes contain a nested accessible type having name I and K type parameters, then the namespace_or_type_name refers to that type constructed with the given type arguments. Si hay más de uno de estos tipos, se selecciona el tipo declarado dentro del tipo más derivado.If there is more than one such type, the type declared within the more derived type is selected. Observe que si el significado de N.I se determina como parte de la resolución de la especificación de clase base N , a continuación, la clase base directa de N se considera que es objeto (clases Base).Note that if the meaning of N.I is being determined as part of resolving the base class specification of N then the direct base class of N is considered to be object (Base classes).
    • En caso contrario, N.I no es válida namespace_or_type_name, y se produce un error en tiempo de compilación.Otherwise, N.I is an invalid namespace_or_type_name, and a compile-time error occurs.

Un namespace_or_type_name tiene permiso para hacer referencia a una clase estática (clases estáticas) solo siA namespace_or_type_name is permitted to reference a static class (Static classes) only if

  • El namespace_or_type_name es el T en un namespace_or_type_name del formulario T.I, oThe namespace_or_type_name is the T in a namespace_or_type_name of the form T.I, or
  • El namespace_or_type_name es el T en un typeof_expression (listas de argumentos1) del formulario typeof(T).The namespace_or_type_name is the T in a typeof_expression (Argument lists1) of the form typeof(T).

Nombres completosFully qualified names

Cada espacio de nombres y el tipo tiene un nombre completo, que identifica el espacio de nombres o tipo entre todos los demás.Every namespace and type has a fully qualified name, which uniquely identifies the namespace or type amongst all others. El nombre completo de un espacio de nombres o tipo N se determina como sigue:The fully qualified name of a namespace or type N is determined as follows:

  • Si N es un miembro del espacio de nombres global, su nombre completo es N.If N is a member of the global namespace, its fully qualified name is N.
  • En caso contrario, es su nombre completo S.N, donde S es el nombre completo del espacio de nombres o tipo en el que N se declara.Otherwise, its fully qualified name is S.N, where S is the fully qualified name of the namespace or type in which N is declared.

En otras palabras, el nombre completo de N es la ruta de acceso jerárquica completa de identificadores que conducen a N, empezando por el espacio de nombres global.In other words, the fully qualified name of N is the complete hierarchical path of identifiers that lead to N, starting from the global namespace. Dado que todos los miembros de un tipo o espacio de nombres deben tener un nombre único, se deduce que el nombre completo de un espacio de nombres o tipo siempre es único.Because every member of a namespace or type must have a unique name, it follows that the fully qualified name of a namespace or type is always unique.

El ejemplo siguiente muestra varias declaraciones de espacio de nombres y tipo junto con sus nombres completos asociados.The example below shows several namespace and type declarations along with their associated fully qualified names.

class A {}                // A

namespace X               // X
{
    class B               // X.B
    {
        class C {}        // X.B.C
    }

    namespace Y           // X.Y
    {
        class D {}        // X.Y.D
    }
}

namespace X.Y             // X.Y
{
    class E {}            // X.Y.E
}

Administración de memoria automáticaAutomatic memory management

C# usa la administración automática de la memoria, lo que libera a los desarrolladores de forma manual, asignar y liberar la memoria ocupada por objetos.C# employs automatic memory management, which frees developers from manually allocating and freeing the memory occupied by objects. Las directivas de administración automática de la memoria se implementan mediante un recolector de elementos no utilizados.Automatic memory management policies are implemented by a garbage collector. El ciclo de vida de administración de memoria de un objeto es como sigue:The memory management life cycle of an object is as follows:

  1. Cuando se crea el objeto, se le asigna memoria, se ejecuta el constructor y el objeto se considera activo.When the object is created, memory is allocated for it, the constructor is run, and the object is considered live.
  2. Si el objeto, o cualquier parte del mismo, no se puede tener acceso a las posibles continuaciones de la ejecución de, aparte de los destructores, se considera el objeto ya no está en uso, y se convierte en apto para su destrucción.If the object, or any part of it, cannot be accessed by any possible continuation of execution, other than the running of destructors, the object is considered no longer in use, and it becomes eligible for destruction. El compilador de C# y el recolector de elementos no utilizados puede analizar el código para determinar qué referencias a un objeto pueden utilizarse en el futuro.The C# compiler and the garbage collector may choose to analyze code to determine which references to an object may be used in the future. Por ejemplo, si una variable local que está en el ámbito es la única referencia existente a un objeto, pero esa variable local nunca se hace referencia en cualquier continuación posible de la ejecución de la ejecución actual del punto en el procedimiento, el recolector de elementos no utilizados puede (pero no es debe) tratar el objeto que ya no usa.For instance, if a local variable that is in scope is the only existing reference to an object, but that local variable is never referred to in any possible continuation of execution from the current execution point in the procedure, the garbage collector may (but is not required to) treat the object as no longer in use.
  3. Una vez que el objeto es elegible para su destrucción, algunas más adelante no se especifica el tiempo el destructor (destructores) (si existe) para el objeto se ejecuta.Once the object is eligible for destruction, at some unspecified later time the destructor (Destructors) (if any) for the object is run. En circunstancias normales el destructor del objeto se ejecuta solo una vez, aunque las API específicas de la implementación pueden permitir que invalidar este comportamiento.Under normal circumstances the destructor for the object is run once only, though implementation-specific APIs may allow this behavior to be overridden.
  4. Una vez que se ejecuta el destructor de un objeto, si ese objeto, o cualquier parte del mismo, no se puede tener acceso a las posibles continuaciones de ejecución, incluida la ejecución de los destructores, el objeto se considera inaccesible y el objeto se convierte en apto para la colección.Once the destructor for an object is run, if that object, or any part of it, cannot be accessed by any possible continuation of execution, including the running of destructors, the object is considered inaccessible and the object becomes eligible for collection.
  5. Por último, en algún momento después de que el objeto se convierte en apto para la recolección, el recolector de elementos no utilizados libera la memoria asociada con ese objeto.Finally, at some time after the object becomes eligible for collection, the garbage collector frees the memory associated with that object.

El recolector de elementos no utilizados mantiene información sobre el uso del objeto y usa esta información para tomar decisiones de administración, de memoria, tales como where en la memoria para localizar un objeto recién creado, cuando reubicar un objeto y cuando un objeto ya no está en uso o es inaccesible.The garbage collector maintains information about object usage, and uses this information to make memory management decisions, such as where in memory to locate a newly created object, when to relocate an object, and when an object is no longer in use or inaccessible.

Al igual que otros lenguajes que asumen la existencia de un recolector de elementos no utilizados, C# está diseñado para que el recolector de elementos no utilizados puede implementar una amplia gama de directivas de administración de memoria.Like other languages that assume the existence of a garbage collector, C# is designed so that the garbage collector may implement a wide range of memory management policies. Por ejemplo, C# no requiere que los destructores se ejecuten o que se recopilan objetos tan pronto como son aptos o que los destructores se ejecute en un orden determinado, o en un subproceso concreto.For instance, C# does not require that destructors be run or that objects be collected as soon as they are eligible, or that destructors be run in any particular order, or on any particular thread.

Se puede controlar el comportamiento del recolector de elementos no utilizados, hasta cierto punto, a través de métodos estáticos en la clase System.GC.The behavior of the garbage collector can be controlled, to some degree, via static methods on the class System.GC. Esta clase puede utilizarse para solicitar una colección a los destructores se ejecutará (o no) y así sucesivamente.This class can be used to request a collection to occur, destructors to be run (or not run), and so forth.

Dado que el recolector de elementos no utilizados se permite una amplia libertad para decidir cuándo debe recolectar objetos y ejecutar destructores, una implementación compatible puede producir un resultado diferente del que se muestra en el código siguiente.Since the garbage collector is allowed wide latitude in deciding when to collect objects and run destructors, a conforming implementation may produce output that differs from that shown by the following code. El programaThe program

using System;

class A
{
    ~A() {
        Console.WriteLine("Destruct instance of A");
    }
}

class B
{
    object Ref;

    public B(object o) {
        Ref = o;
    }

    ~B() {
        Console.WriteLine("Destruct instance of B");
    }
}

class Test
{
    static void Main() {
        B b = new B(new A());
        b = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}

crea una instancia de clase A y una instancia de la clase B.creates an instance of class A and an instance of class B. Estos objetos son candidatos para la recolección cuando la variable b se asigna el valor null, ya que esta tarde es imposible que cualquier código escrito por el usuario para tener acceso a ellos.These objects become eligible for garbage collection when the variable b is assigned the value null, since after this time it is impossible for any user-written code to access them. El resultado puede serThe output could be either

Destruct instance of A
Destruct instance of B

oor

Destruct instance of B
Destruct instance of A

Dado que el idioma impone ninguna restricción en el orden en que los objetos se recolectan.because the language imposes no constraints on the order in which objects are garbage collected.

En casos concretos, la distinción entre "elegible para su destrucción" y "elegible para la recolección" puede ser importante.In subtle cases, the distinction between "eligible for destruction" and "eligible for collection" can be important. Por ejemplo,For example,

using System;

class A
{
    ~A() {
        Console.WriteLine("Destruct instance of A");
    }

    public void F() {
        Console.WriteLine("A.F");
        Test.RefA = this;
    }
}

class B
{
    public A Ref;

    ~B() {
        Console.WriteLine("Destruct instance of B");
        Ref.F();
    }
}

class Test
{
    public static A RefA;
    public static B RefB;

    static void Main() {
        RefB = new B();
        RefA = new A();
        RefB.Ref = RefA;
        RefB = null;
        RefA = null;

        // A and B now eligible for destruction
        GC.Collect();
        GC.WaitForPendingFinalizers();

        // B now eligible for collection, but A is not
        if (RefA != null)
            Console.WriteLine("RefA is not null");
    }
}

En el programa anterior, si opta por el recolector de elementos no utilizados ejecuta el destructor de A antes que el destructor de B, a continuación, el resultado de este programa puede ser:In the above program, if the garbage collector chooses to run the destructor of A before the destructor of B, then the output of this program might be:

Destruct instance of A
Destruct instance of B
A.F
RefA is not null

Tenga en cuenta que aunque la instancia de A no estaba en uso y Adel destructor se ejecutó, sigue siendo posible para los métodos de A (en este caso, F) que se llame desde otro destructor.Note that although the instance of A was not in use and A's destructor was run, it is still possible for methods of A (in this case, F) to be called from another destructor. Además, tenga en cuenta que la ejecución de un destructor puede producir un objeto vuelva a ser utilizable desde el programa principal.Also, note that running of a destructor may cause an object to become usable from the mainline program again. En este caso, la ejecución de Bdel destructor hizo que una instancia de A que anteriormente estaba no en uso para ser accesible desde la referencia activa Test.RefA.In this case, the running of B's destructor caused an instance of A that was previously not in use to become accessible from the live reference Test.RefA. Después de llamar a WaitForPendingFinalizers, la instancia de B es apto para la colección, pero la instancia de A no lo es, debido a la referencia Test.RefA.After the call to WaitForPendingFinalizers, the instance of B is eligible for collection, but the instance of A is not, because of the reference Test.RefA.

Para evitar confusiones y comportamientos inesperados, por lo general es una buena idea para los destructores para realizar la limpieza únicamente en datos almacenados en los campos del objeto y no para realizar acciones en los objetos que se hace referencia o campos estáticos.To avoid confusion and unexpected behavior, it is generally a good idea for destructors to only perform cleanup on data stored in their object's own fields, and not to perform any actions on referenced objects or static fields.

Es una alternativa al uso de los destructores permitir que una clase implementa la System.IDisposable interfaz.An alternative to using destructors is to let a class implement the System.IDisposable interface. Esto permite al cliente del objeto determinar cuándo se debe liberar los recursos del objeto, normalmente mediante el acceso a los objetos como un recurso en un using instrucción (la instrucción using).This allows the client of the object to determine when to release the resources of the object, typically by accessing the object as a resource in a using statement (The using statement).

Orden de ejecuciónExecution order

Ejecución de un programa de C# continúa tal que se conservan los efectos secundarios de cada subproceso en ejecución en puntos críticos de ejecución.Execution of a C# program proceeds such that the side effects of each executing thread are preserved at critical execution points. Un efecto se define como una lectura o escritura de un campo volátil, una escritura en una variable no volátil, la escritura en un recurso externo y el inicio de una excepción.A side effect is defined as a read or write of a volatile field, a write to a non-volatile variable, a write to an external resource, and the throwing of an exception. Los puntos de ejecución críticos en el que debe conservarse el orden de estos efectos son referencias a campos volátiles (campos volátiles), lock instrucciones (la instrucción lock), y creación de subprocesos y terminación.The critical execution points at which the order of these side effects must be preserved are references to volatile fields (Volatile fields), lock statements (The lock statement), and thread creation and termination. El entorno de ejecución es libre de cambiar el orden de ejecución de un programa de C#, sujeto a las restricciones siguientes:The execution environment is free to change the order of execution of a C# program, subject to the following constraints:

  • Se conservará la dependencia de datos dentro de un subproceso de ejecución.Data dependence is preserved within a thread of execution. Es decir, el valor de cada variable se calcula como si todas las instrucciones en el subproceso se ejecutaron en el orden del programa original.That is, the value of each variable is computed as if all statements in the thread were executed in original program order.
  • Las reglas se conservan el orden de inicialización (inicialización de campos y inicializadores de variables).Initialization ordering rules are preserved (Field initialization and Variable initializers).
  • El orden de los efectos secundarios se conserva con respecto a las lecturas y escrituras (campos volátiles).The ordering of side effects is preserved with respect to volatile reads and writes (Volatile fields). Además, el entorno de ejecución no necesitará evaluar parte de una expresión si puede deducir que el valor de la expresión no se utiliza y que no hay efectos secundarios necesarios se crean (incluidos los causados por una llamada a un método o tener acceso a un campo volátil).Additionally, the execution environment need not evaluate part of an expression if it can deduce that that expression's value is not used and that no needed side effects are produced (including any caused by calling a method or accessing a volatile field). Cuando se interrumpe la ejecución del programa un evento asincrónico (por ejemplo, una excepción iniciada por otro subproceso), no se garantiza que los efectos secundarios observables son visibles en el orden del programa original.When program execution is interrupted by an asynchronous event (such as an exception thrown by another thread), it is not guaranteed that the observable side effects are visible in the original program order.