TiposTypes
Los tipos del lenguaje C# se dividen en dos categorías principales: tipos de valor _ y _tipos de referencia*.The types of the C# language are divided into two main categories: value types _ and _reference types*. Ambos tipos de valor y tipos de referencia pueden ser tipos genéricos, que toman uno o varios parámetros de tipo _ * * *.Both value types and reference types may be generic types, which take one or more _*type parameters**. Los parámetros de tipo pueden designar tanto tipos de valor como tipos de referencia.Type parameters can designate both value types and reference types.
type
: value_type
| reference_type
| type_parameter
| type_unsafe
;
La categoría final de tipos, punteros, solo está disponible en código no seguro.The final category of types, pointers, is available only in unsafe code. Esto se describe con más detalle en tipos de puntero.This is discussed further in Pointer types.
Los tipos de valor se diferencian de los tipos de referencia en que las variables de los tipos de valor contienen directamente sus datos, mientras que las variables de los tipos de referencia almacenan referencias en sus datos, lo que se conoce como "objetos *".Value types differ from reference types in that variables of the value types directly contain their data, whereas variables of the reference types store references _ to their data, the latter being known as _objects**. Con los tipos de referencia, es posible que dos variables hagan referencia al mismo objeto y, por lo tanto, las operaciones en una variable afecten al objeto al que hace referencia la otra variable.With reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. Con los tipos de valor, cada variable tiene su propia copia de los datos y no es posible que las operaciones en una afecten a la otra.With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other.
El sistema de tipos de C# está unificado, de modo que un valor de cualquier tipo se puede tratar como un objeto.C#'s type system is unified such that a value of any type can be treated as an object. Todos los tipos de C# directa o indirectamente se derivan del tipo de clase object
, y object
es la clase base definitiva de todos los tipos.Every type in C# directly or indirectly derives from the object
class type, and object
is the ultimate base class of all types. Los valores de tipos de referencia se tratan como objetos mediante la visualización de los valores como tipo object
.Values of reference types are treated as objects simply by viewing the values as type object
. Los valores de los tipos de valor se tratan como objetos realizando las operaciones de conversión boxing y unboxing (conversión boxing y conversión unboxing).Values of value types are treated as objects by performing boxing and unboxing operations (Boxing and unboxing).
Tipos de valorValue types
Un tipo de valor es un tipo de estructura o un tipo de enumeración.A value type is either a struct type or an enumeration type. C# proporciona un conjunto de tipos de struct predefinidos denominados tipos simples.C# provides a set of predefined struct types called the simple types. Los tipos simples se identifican mediante palabras reservadas.The simple types are identified through reserved words.
value_type
: struct_type
| enum_type
;
struct_type
: type_name
| simple_type
| nullable_type
;
simple_type
: numeric_type
| 'bool'
;
numeric_type
: integral_type
| floating_point_type
| 'decimal'
;
integral_type
: 'sbyte'
| 'byte'
| 'short'
| 'ushort'
| 'int'
| 'uint'
| 'long'
| 'ulong'
| 'char'
;
floating_point_type
: 'float'
| 'double'
;
nullable_type
: non_nullable_value_type '?'
;
non_nullable_value_type
: type
;
enum_type
: type_name
;
A diferencia de una variable de un tipo de referencia, una variable de un tipo de valor solo puede contener el valor null
si el tipo de valor es un tipo que acepta valores NULL.Unlike a variable of a reference type, a variable of a value type can contain the value null
only if the value type is a nullable type. Para cada tipo de valor que no acepta valores NULL, hay un tipo de valor que acepta valores NULL correspondiente que denota el mismo conjunto de valores más el valor null
.For every non-nullable value type there is a corresponding nullable value type denoting the same set of values plus the value null
.
La asignación a una variable de un tipo de valor crea una copia del valor que se va a asignar.Assignment to a variable of a value type creates a copy of the value being assigned. Esto difiere de la asignación a una variable de un tipo de referencia, que copia la referencia pero no el objeto identificado por la referencia.This differs from assignment to a variable of a reference type, which copies the reference but not the object identified by the reference.
Tipo System. ValueTypeThe System.ValueType type
Todos los tipos de valor heredan implícitamente de la clase System.ValueType
, que, a su vez, hereda de la clase object
.All value types implicitly inherit from the class System.ValueType
, which, in turn, inherits from class object
. No es posible que ningún tipo derive de un tipo de valor y, por tanto, los tipos de valor están sellados implícitamente (clases selladas).It is not possible for any type to derive from a value type, and value types are thus implicitly sealed (Sealed classes).
Tenga en cuenta que System.ValueType
no es un value_type.Note that System.ValueType
is not itself a value_type. En su lugar, es una class_type de la que se derivan automáticamente todos los value_type s.Rather, it is a class_type from which all value_type s are automatically derived.
Constructores predeterminadosDefault constructors
Todos los tipos de valor declaran implícitamente un constructor de instancia sin parámetros público denominado *constructor predeterminado _.All value types implicitly declare a public parameterless instance constructor called the *default constructor _. El constructor predeterminado devuelve una instancia inicializada en cero, conocida como el valor _ default* para el tipo de valor:The default constructor returns a zero-initialized instance known as the _ default value* for the value type:
- Para todos los Simple_Type s, el valor predeterminado es el valor generado por un patrón de bits de todos los ceros:For all simple_type s, the default value is the value produced by a bit pattern of all zeros:
- Para
sbyte
,byte
,short
,ushort
,int
,uint
,long
yulong
, el valor predeterminado es0
.Forsbyte
,byte
,short
,ushort
,int
,uint
,long
, andulong
, the default value is0
. - En
char
, el valor predeterminado es'\x0000'
.Forchar
, the default value is'\x0000'
. - En
float
, el valor predeterminado es0.0f
.Forfloat
, the default value is0.0f
. - En
double
, el valor predeterminado es0.0d
.Fordouble
, the default value is0.0d
. - En
decimal
, el valor predeterminado es0.0m
.Fordecimal
, the default value is0.0m
. - En
bool
, el valor predeterminado esfalse
.Forbool
, the default value isfalse
.
- Para
- Para un enum_type
E
, el valor predeterminado es0
, convertido al tipoE
.For an enum_typeE
, the default value is0
, converted to the typeE
. - Para un struct_type, el valor predeterminado es el valor generado al establecer todos los campos de tipo de valor en sus valores predeterminados y todos los campos de tipo de referencia en
null
.For a struct_type, the default value is the value produced by setting all value type fields to their default value and all reference type fields tonull
. - Para un nullable_type el valor predeterminado es una instancia para la que la
HasValue
propiedad es false y laValue
propiedad no está definida.For a nullable_type the default value is an instance for which theHasValue
property is false and theValue
property is undefined. El valor predeterminado también se conoce como el valor null del tipo que acepta valores NULL.The default value is also known as the null value of the nullable type.
Al igual que cualquier otro constructor de instancia, el constructor predeterminado de un tipo de valor se invoca mediante el new
operador.Like any other instance constructor, the default constructor of a value type is invoked using the new
operator. Por motivos de eficacia, este requisito no está diseñado para tener realmente la implementación que genera una llamada al constructor.For efficiency reasons, this requirement is not intended to actually have the implementation generate a constructor call. En el ejemplo siguiente, las variables i
y j
se inicializan en cero.In the example below, variables i
and j
are both initialized to zero.
class A
{
void F() {
int i = 0;
int j = new int();
}
}
Dado que cada tipo de valor tiene implícitamente un constructor de instancia sin parámetros público, no es posible que un tipo de struct contenga una declaración explícita de un constructor sin parámetros.Because every value type implicitly has a public parameterless instance constructor, it is not possible for a struct type to contain an explicit declaration of a parameterless constructor. Sin embargo, se permite que un tipo de estructura declare constructores de instancia con parámetros (constructores).A struct type is however permitted to declare parameterized instance constructors (Constructors).
Tipos de estructuraStruct types
Un tipo de estructura es un tipo de valor que puede declarar constantes, campos, métodos, propiedades, indizadores, operadores, constructores de instancias, constructores estáticos y tipos anidados.A struct type is a value type that can declare constants, fields, methods, properties, indexers, operators, instance constructors, static constructors, and nested types. La declaración de tipos de struct se describe en declaraciones de struct.The declaration of struct types is described in Struct declarations.
Tipos simplesSimple types
C# proporciona un conjunto de tipos de struct predefinidos denominados tipos simples.C# provides a set of predefined struct types called the simple types. Los tipos simples se identifican mediante palabras reservadas, pero estas palabras reservadas son simplemente alias para los tipos de struct predefinidos en el System
espacio de nombres, tal como se describe en la tabla siguiente.The simple types are identified through reserved words, but these reserved words are simply aliases for predefined struct types in the System
namespace, as described in the table below.
Palabra reservadaReserved word | Tipo con aliasAliased type |
---|---|
sbyte |
System.SByte |
byte |
System.Byte |
short |
System.Int16 |
ushort |
System.UInt16 |
int |
System.Int32 |
uint |
System.UInt32 |
long |
System.Int64 |
ulong |
System.UInt64 |
char |
System.Char |
float |
System.Single |
double |
System.Double |
bool |
System.Boolean |
decimal |
System.Decimal |
Dado que un tipo simple incluye un alias para un tipo de estructura, cada tipo simple tiene miembros.Because a simple type aliases a struct type, every simple type has members. Por ejemplo, int
tiene los miembros declarados en System.Int32
y los miembros heredados de System.Object
, y se permiten las siguientes instrucciones:For example, int
has the members declared in System.Int32
and the members inherited from System.Object
, and the following statements are permitted:
int i = int.MaxValue; // System.Int32.MaxValue constant
string s = i.ToString(); // System.Int32.ToString() instance method
string t = 123.ToString(); // System.Int32.ToString() instance method
Los tipos simples se diferencian de otros tipos struct en que permiten determinadas operaciones adicionales:The simple types differ from other struct types in that they permit certain additional operations:
- La mayoría de los tipos simples permiten crear valores escribiendo literales (literales).Most simple types permit values to be created by writing literals (Literals). Por ejemplo,
123
es un literal de tipoint
y'a'
es un literal de tipochar
.For example,123
is a literal of typeint
and'a'
is a literal of typechar
. C# no hace ningún aprovisionamiento de los literales de tipos struct en general, y los valores no predeterminados de otros tipos struct siempre se crean en última instancia mediante constructores de instancias de esos tipos de estructura.C# makes no provision for literals of struct types in general, and non-default values of other struct types are ultimately always created through instance constructors of those struct types. - Cuando los operandos de una expresión son constantes de tipo simple, es posible que el compilador evalúe la expresión en tiempo de compilación.When the operands of an expression are all simple type constants, it is possible for the compiler to evaluate the expression at compile-time. Este tipo de expresión se conoce como constant_expression (expresiones constantes).Such an expression is known as a constant_expression (Constant expressions). Las expresiones que implican operadores definidos por otros tipos struct no se consideran expresiones constantes.Expressions involving operators defined by other struct types are not considered to be constant expressions.
- A través
const
de las declaraciones, es posible declarar constantes de los tipos simples (constantes).Throughconst
declarations it is possible to declare constants of the simple types (Constants). No es posible tener constantes de otros tipos struct, pero los campos proporcionan un efecto similarstatic readonly
.It is not possible to have constants of other struct types, but a similar effect is provided bystatic readonly
fields. - Las conversiones que implican tipos simples pueden participar en la evaluación de operadores de conversión definidos por otros tipos de struct, pero un operador de conversión definido por el usuario nunca puede participar en la evaluación de otro operador definido por el usuario (evaluación de conversiones definidas por el usuario).Conversions involving simple types can participate in evaluation of conversion operators defined by other struct types, but a user-defined conversion operator can never participate in evaluation of another user-defined operator (Evaluation of user-defined conversions).
Tipos enterosIntegral types
C# admite nueve tipos enteros: sbyte
, byte
, short
, ushort
, int
, uint
, long
, ulong
y char
.C# supports nine integral types: sbyte
, byte
, short
, ushort
, int
, uint
, long
, ulong
, and char
. Los tipos enteros tienen los siguientes tamaños y rangos de valores:The integral types have the following sizes and ranges of values:
- El
sbyte
tipo representa enteros de 8 bits con signo con valores comprendidos entre-128 y 127.Thesbyte
type represents signed 8-bit integers with values between -128 and 127. - El
byte
tipo representa enteros de 8 bits sin signo con valores comprendidos entre 0 y 255.Thebyte
type represents unsigned 8-bit integers with values between 0 and 255. - El
short
tipo representa enteros de 16 bits con signo con valores comprendidos entre-32768 y 32767.Theshort
type represents signed 16-bit integers with values between -32768 and 32767. - El
ushort
tipo representa enteros de 16 bits sin signo con valores comprendidos entre 0 y 65535.Theushort
type represents unsigned 16-bit integers with values between 0 and 65535. - El
int
tipo representa enteros de 32 bits con signo con valores comprendidos entre-2147483648 y 2147483647.Theint
type represents signed 32-bit integers with values between -2147483648 and 2147483647. - El
uint
tipo representa enteros de 32 bits sin signo con valores comprendidos entre 0 y 4294967295.Theuint
type represents unsigned 32-bit integers with values between 0 and 4294967295. - El
long
tipo representa enteros de 64 bits con signo con valores comprendidos entre-9223372036854775808 y 9223372036854775807.Thelong
type represents signed 64-bit integers with values between -9223372036854775808 and 9223372036854775807. - El
ulong
tipo representa enteros de 64 bits sin signo con valores comprendidos entre 0 y 18446744073709551615.Theulong
type represents unsigned 64-bit integers with values between 0 and 18446744073709551615. - El
char
tipo representa enteros de 16 bits sin signo con valores comprendidos entre 0 y 65535.Thechar
type represents unsigned 16-bit integers with values between 0 and 65535. El conjunto de valores posibles para el tipochar
corresponde al juego de caracteres Unicode.The set of possible values for thechar
type corresponds to the Unicode character set. Aunquechar
tiene la misma representación queushort
, no todas las operaciones permitidas en un tipo se permiten en el otro.Althoughchar
has the same representation asushort
, not all operations permitted on one type are permitted on the other.
Los operadores unarios y binarios de tipo entero siempre operan con una precisión de 32 bits con signo, una precisión de 32 bits sin signo, una precisión de 64 con signo o una precisión de bit 64 sin signo:The integral-type unary and binary operators always operate with signed 32-bit precision, unsigned 32-bit precision, signed 64-bit precision, or unsigned 64-bit precision:
- En el caso de los operadores unario
+
y~
, el operando se convierte al tipoT
, dondeT
es el primero deint
,,uint
long
yulong
que puede representar completamente todos los valores posibles del operando.For the unary+
and~
operators, the operand is converted to typeT
, whereT
is the first ofint
,uint
,long
, andulong
that can fully represent all possible values of the operand. La operación se realiza entonces con la precisión del tipoT
y el tipo del resultado esT
.The operation is then performed using the precision of typeT
, and the type of the result isT
. - Para el operador unario
-
, el operando se convierte al tipoT
, dondeT
es el primero deint
ylong
que puede representar completamente todos los valores posibles del operando.For the unary-
operator, the operand is converted to typeT
, whereT
is the first ofint
andlong
that can fully represent all possible values of the operand. La operación se realiza entonces con la precisión del tipoT
y el tipo del resultado esT
.The operation is then performed using the precision of typeT
, and the type of the result isT
. El operador unario-
no se puede aplicar a operandos de tipoulong
.The unary-
operator cannot be applied to operands of typeulong
. - En el caso de los operadores binarios
+
,,,,,,,,,,-
*
/
%
&
^
|
==
!=
>
,<
, y>=
<=
, los operandos se convierten al tipoT
, dondeT
es el primero deint
,uint
, y,long
ulong
que puede representar por completo todos los valores posibles de ambos operandos.For the binary+
,-
,*
,/
,%
,&
,^
,|
,==
,!=
,>
,<
,>=
, and<=
operators, the operands are converted to typeT
, whereT
is the first ofint
,uint
,long
, andulong
that can fully represent all possible values of both operands. La operación se realiza entonces con la precisión del tipoT
y el tipo del resultado esT
(obool
para los operadores relacionales).The operation is then performed using the precision of typeT
, and the type of the result isT
(orbool
for the relational operators). No se permite que un operando sea de tipolong
y el otro para ser de tipoulong
con los operadores binarios.It is not permitted for one operand to be of typelong
and the other to be of typeulong
with the binary operators. - En el caso de los operadores binarios
<<
y>>
, el operando izquierdo se convierte al tipoT
, dondeT
es el primero deint
,, y,uint
long
ulong
que puede representar completamente todos los valores posibles del operando.For the binary<<
and>>
operators, the left operand is converted to typeT
, whereT
is the first ofint
,uint
,long
, andulong
that can fully represent all possible values of the operand. La operación se realiza entonces con la precisión del tipoT
y el tipo del resultado esT
.The operation is then performed using the precision of typeT
, and the type of the result isT
.
El char
tipo se clasifica como un tipo entero, pero difiere de los demás tipos enteros de dos maneras:The char
type is classified as an integral type, but it differs from the other integral types in two ways:
- No hay ninguna conversión implícita de otros tipos al tipo
char
.There are no implicit conversions from other types to thechar
type. En concreto, aunque lossbyte
tipos,byte
yushort
tienen intervalos de valores que se pueden representar completamente con elchar
tipo, las conversiones implícitas desbyte
,byte
oushort
char
no existen.In particular, even though thesbyte
,byte
, andushort
types have ranges of values that are fully representable using thechar
type, implicit conversions fromsbyte
,byte
, orushort
tochar
do not exist. - Las constantes del
char
tipo deben escribirse como character_literal s o como integer_literal s en combinación con una conversión al tipochar
.Constants of thechar
type must be written as character_literal s or as integer_literal s in combination with a cast to typechar
. Por ejemplo,(char)10
es lo mismo que'\x000A'
.For example,(char)10
is the same as'\x000A'
.
Los checked
unchecked
operadores and y las instrucciones se utilizan para controlar la comprobación de desbordamiento de las operaciones aritméticas de tipo entero y las conversiones (los operadores Checked y unchecked).The checked
and unchecked
operators and statements are used to control overflow checking for integral-type arithmetic operations and conversions (The checked and unchecked operators). En un checked
contexto, un desbordamiento produce un error en tiempo de compilación o provoca System.OverflowException
que se produzca una excepción.In a checked
context, an overflow produces a compile-time error or causes a System.OverflowException
to be thrown. En un unchecked
contexto, se omiten los desbordamientos y se descartan los bits de orden superior que no caben en el tipo de destino.In an unchecked
context, overflows are ignored and any high-order bits that do not fit in the destination type are discarded.
Tipos de punto flotanteFloating point types
C# admite dos tipos de punto flotante: float
y double
.C# supports two floating point types: float
and double
. Los float
double
tipos y se representan mediante los formatos IEEE 754 de precisión sencilla de 32 bits y de doble precisión de 64 bits, que proporcionan los siguientes conjuntos de valores:The float
and double
types are represented using the 32-bit single-precision and 64-bit double-precision IEEE 754 formats, which provide the following sets of values:
- Cero positivo y cero negativo.Positive zero and negative zero. En la mayoría de los casos, cero positivo y cero negativo se comportan exactamente igual que el valor cero simple, pero ciertas operaciones distinguen entre los dos (operador de división).In most situations, positive zero and negative zero behave identically as the simple value zero, but certain operations distinguish between the two (Division operator).
- Infinito positivo y infinito negativo.Positive infinity and negative infinity. Los infinitos se generan mediante operaciones como la división por cero de un número distinto de cero.Infinities are produced by such operations as dividing a non-zero number by zero. Por ejemplo,
1.0 / 0.0
produce infinito positivo y-1.0 / 0.0
produce infinito negativo.For example,1.0 / 0.0
yields positive infinity, and-1.0 / 0.0
yields negative infinity. - El valor no numérico , a menudo abreviado como Nan.The Not-a-Number value, often abbreviated NaN. Los Nan se generan mediante operaciones de punto flotante no válidas, como la división de cero por cero.NaNs are produced by invalid floating-point operations, such as dividing zero by zero.
- El conjunto finito de valores distintos de cero del formulario
s * m * 2^e
, dondes
es 1 o-1, ym
ye
vienen determinados por el tipo de punto flotante determinado: parafloat
,0 < m < 2^24
y-149 <= e <= 104
, y paradouble
,0 < m < 2^53
y-1075 <= e <= 970
.The finite set of non-zero values of the forms * m * 2^e
, wheres
is 1 or -1, andm
ande
are determined by the particular floating-point type: Forfloat
,0 < m < 2^24
and-149 <= e <= 104
, and fordouble
,0 < m < 2^53
and-1075 <= e <= 970
. Los números de punto flotante desnormalizados se consideran valores distintos de cero válidos.Denormalized floating-point numbers are considered valid non-zero values.
El float
tipo puede representar valores comprendidos entre aproximadamente 1.5 * 10^-45
y 3.4 * 10^38
con una precisión de 7 dígitos.The float
type can represent values ranging from approximately 1.5 * 10^-45
to 3.4 * 10^38
with a precision of 7 digits.
El double
tipo puede representar valores comprendidos entre aproximadamente 5.0 * 10^-324
y 1.7 × 10^308
con una precisión de 15-16 dígitos.The double
type can represent values ranging from approximately 5.0 * 10^-324
to 1.7 × 10^308
with a precision of 15-16 digits.
Si uno de los operandos de un operador binario es de un tipo de punto flotante, el otro operando debe ser de un tipo entero o de un tipo de punto flotante, y la operación se evalúa como sigue:If one of the operands of a binary operator is of a floating-point type, then the other operand must be of an integral type or a floating-point type, and the operation is evaluated as follows:
- Si uno de los operandos es de un tipo entero, ese operando se convierte en el tipo de punto flotante del otro operando.If one of the operands is of an integral type, then that operand is converted to the floating-point type of the other operand.
- Después, si alguno de los operandos es de tipo
double
, el otro operando se convierte endouble
, la operación se realiza utilizando al menos eldouble
intervalo y la precisión, y el tipo del resultado esdouble
(obool
para los operadores relacionales).Then, if either of the operands is of typedouble
, the other operand is converted todouble
, the operation is performed using at leastdouble
range and precision, and the type of the result isdouble
(orbool
for the relational operators). - De lo contrario, la operación se realiza utilizando al menos el
float
intervalo y la precisión, y el tipo del resultado esfloat
(obool
para los operadores relacionales).Otherwise, the operation is performed using at leastfloat
range and precision, and the type of the result isfloat
(orbool
for the relational operators).
Los operadores de punto flotante, incluidos los operadores de asignación, nunca generan excepciones.The floating-point operators, including the assignment operators, never produce exceptions. En su lugar, en situaciones excepcionales, las operaciones de punto flotante producen cero, infinito o NaN, como se describe a continuación:Instead, in exceptional situations, floating-point operations produce zero, infinity, or NaN, as described below:
- Si el resultado de una operación de punto flotante es demasiado pequeño para el formato de destino, el resultado de la operación se convierte en cero positivo o negativo.If the result of a floating-point operation is too small for the destination format, the result of the operation becomes positive zero or negative zero.
- Si el resultado de una operación de punto flotante es demasiado grande para el formato de destino, el resultado de la operación se convierte en infinito positivo o infinito negativo.If the result of a floating-point operation is too large for the destination format, the result of the operation becomes positive infinity or negative infinity.
- Si una operación de punto flotante no es válida, el resultado de la operación se convierte en NaN.If a floating-point operation is invalid, the result of the operation becomes NaN.
- Si uno o los dos operandos de una operación de punto flotante son NaN, el resultado de la operación se convierte en NaN.If one or both operands of a floating-point operation is NaN, the result of the operation becomes NaN.
Las operaciones de punto flotante se pueden realizar con una precisión mayor que el tipo de resultado de la operación.Floating-point operations may be performed with higher precision than the result type of the operation. Por ejemplo, algunas arquitecturas de hardware admiten un tipo de punto flotante "extendido" o "Long Double" con un intervalo y una precisión mayores que el double
tipo y realizan implícitamente todas las operaciones de punto flotante con este tipo de precisión superior.For example, some hardware architectures support an "extended" or "long double" floating-point type with greater range and precision than the double
type, and implicitly perform all floating-point operations using this higher precision type. Solo con un costo excesivo en el rendimiento se pueden realizar estas arquitecturas de hardware para realizar operaciones de punto flotante con menos precisión y, en lugar de requerir una implementación para que se pierda rendimiento y precisión, C# permite usar un tipo de precisión mayor para todas las operaciones de punto flotante.Only at excessive cost in performance can such hardware architectures be made to perform floating-point operations with less precision, and rather than require an implementation to forfeit both performance and precision, C# allows a higher precision type to be used for all floating-point operations. Aparte de ofrecer resultados más precisos, esto rara vez tiene efectos medibles.Other than delivering more precise results, this rarely has any measurable effects. Sin embargo, en las expresiones con el formato x * y / z
, donde la multiplicación genera un resultado que está fuera del double
intervalo, pero la división posterior devuelve el resultado temporal al double
intervalo, el hecho de que la expresión se evalúe en un formato de intervalo más alto puede provocar que se genere un resultado finito en lugar de un infinito.However, in expressions of the form x * y / z
, where the multiplication produces a result that is outside the double
range, but the subsequent division brings the temporary result back into the double
range, the fact that the expression is evaluated in a higher range format may cause a finite result to be produced instead of an infinity.
El tipo decimalThe decimal type
El tipo decimal
es un tipo de datos de 128 bits adecuado para cálculos financieros y monetarios.The decimal
type is a 128-bit data type suitable for financial and monetary calculations. El decimal
tipo puede representar valores comprendidos entre 1.0 * 10^-28
y aproximadamente 7.9 * 10^28
con 28-29 dígitos significativos.The decimal
type can represent values ranging from 1.0 * 10^-28
to approximately 7.9 * 10^28
with 28-29 significant digits.
El conjunto finito de valores de tipo decimal
tiene el formato (-1)^s * c * 10^-e
, donde el signo s
es 0 o 1, el coeficiente c
lo proporciona 0 <= *c* < 2^96
y la escala e
es tal que 0 <= e <= 28
. El decimal
tipo no admite ceros con signo, infinitos o Nan.The finite set of values of type decimal
are of the form (-1)^s * c * 10^-e
, where the sign s
is 0 or 1, the coefficient c
is given by 0 <= *c* < 2^96
, and the scale e
is such that 0 <= e <= 28
.The decimal
type does not support signed zeros, infinities, or NaN's. Un decimal
se representa como un entero de 96 bits escalado por una potencia de diez.A decimal
is represented as a 96-bit integer scaled by a power of ten. Para decimal
s con un valor absoluto menor que 1.0m
, el valor es exacto hasta la posición decimal 28, pero no más.For decimal
s with an absolute value less than 1.0m
, the value is exact to the 28th decimal place, but no further. Para decimal
s con un valor absoluto mayor o igual que 1.0m
, el valor es exacto a 28 o 29 dígitos.For decimal
s with an absolute value greater than or equal to 1.0m
, the value is exact to 28 or 29 digits. Al contrario que float
los double
tipos de datos y, los números fraccionarios decimales como 0,1 se pueden representar exactamente en la decimal
representación.Contrary to the float
and double
data types, decimal fractional numbers such as 0.1 can be represented exactly in the decimal
representation. En las float
double
representaciones y, estos números suelen ser fracciones infinitas, por lo que las representaciones son más propensas a errores de redondeo.In the float
and double
representations, such numbers are often infinite fractions, making those representations more prone to round-off errors.
Si uno de los operandos de un operador binario es de tipo decimal
, el otro operando debe ser de un tipo entero o de tipo decimal
.If one of the operands of a binary operator is of type decimal
, then the other operand must be of an integral type or of type decimal
. Si hay un operando de tipo entero, se convierte en decimal
antes de que se realice la operación.If an integral type operand is present, it is converted to decimal
before the operation is performed.
El resultado de una operación con valores de tipo decimal
es que resultaría de calcular un resultado exacto (conservando la escala, tal y como se define para cada operador) y, a continuación, redondear para ajustarse a la representación.The result of an operation on values of type decimal
is that which would result from calculating an exact result (preserving scale, as defined for each operator) and then rounding to fit the representation. Los resultados se redondean al valor representable más cercano y, cuando un resultado está igualmente cerca de dos valores representables, al valor que tiene un número par en la posición del dígito menos significativo (esto se conoce como "redondeo bancario").Results are rounded to the nearest representable value, and, when a result is equally close to two representable values, to the value that has an even number in the least significant digit position (this is known as "banker's rounding"). Un resultado de cero siempre tiene un signo de 0 y una escala de 0.A zero result always has a sign of 0 and a scale of 0.
Si una operación aritmética decimal produce un valor menor o igual que 5 * 10^-29
en valor absoluto, el resultado de la operación se convierte en cero.If a decimal arithmetic operation produces a value less than or equal to 5 * 10^-29
in absolute value, the result of the operation becomes zero. Si una decimal
operación aritmética genera un resultado que es demasiado grande para el decimal
formato, System.OverflowException
se produce una excepción.If a decimal
arithmetic operation produces a result that is too large for the decimal
format, a System.OverflowException
is thrown.
El decimal
tipo tiene mayor precisión pero menor que los tipos de punto flotante.The decimal
type has greater precision but smaller range than the floating-point types. Por lo tanto, las conversiones de los tipos de punto flotante a decimal
pueden producir excepciones de desbordamiento, y las conversiones de decimal
a los tipos de punto flotante podrían provocar la pérdida de precisión.Thus, conversions from the floating-point types to decimal
might produce overflow exceptions, and conversions from decimal
to the floating-point types might cause loss of precision. Por estos motivos, no existe ninguna conversión implícita entre los tipos de punto flotante y decimal
, y sin conversiones explícitas, no es posible mezclar los operandos y el punto flotante decimal
en la misma expresión.For these reasons, no implicit conversions exist between the floating-point types and decimal
, and without explicit casts, it is not possible to mix floating-point and decimal
operands in the same expression.
Tipo boolThe bool type
El bool
tipo representa las cantidades lógicas booleanas.The bool
type represents boolean logical quantities. Los valores posibles de tipo bool
son true
y false
.The possible values of type bool
are true
and false
.
No existe ninguna conversión estándar entre bool
y otros tipos.No standard conversions exist between bool
and other types. En concreto, el bool
tipo es distinto e independiente de los tipos enteros, y bool
no se puede usar un valor en lugar de un valor entero, y viceversa.In particular, the bool
type is distinct and separate from the integral types, and a bool
value cannot be used in place of an integral value, and vice versa.
En los lenguajes C y C++, un valor entero o de punto flotante cero, o un puntero nulo se puede convertir al valor booleano false
, y un valor entero distinto de cero o de punto flotante, o un puntero no nulo se puede convertir al valor booleano true
.In the C and C++ languages, a zero integral or floating-point value, or a null pointer can be converted to the boolean value false
, and a non-zero integral or floating-point value, or a non-null pointer can be converted to the boolean value true
. En C#, estas conversiones se realizan comparando explícitamente un valor entero o de punto flotante en cero, o comparando explícitamente una referencia de objeto a null
.In C#, such conversions are accomplished by explicitly comparing an integral or floating-point value to zero, or by explicitly comparing an object reference to null
.
Tipos de enumeraciónEnumeration types
Un tipo de enumeración es un tipo distinto con constantes con nombre.An enumeration type is a distinct type with named constants. Cada tipo de enumeración tiene un tipo subyacente, que debe ser byte
, sbyte
, short
, ushort
, int
, uint
long
o ulong
.Every enumeration type has an underlying type, which must be byte
, sbyte
, short
, ushort
, int
, uint
, long
or ulong
. El conjunto de valores del tipo de enumeración es el mismo que el conjunto de valores del tipo subyacente.The set of values of the enumeration type is the same as the set of values of the underlying type. Los valores del tipo de enumeración no están restringidos a los valores de las constantes con nombre.Values of the enumeration type are not restricted to the values of the named constants. Los tipos de enumeración se definen mediante declaraciones de enumeración (declaracionesde enumeración).Enumeration types are defined through enumeration declarations (Enum declarations).
Tipos que aceptan valores NULLNullable types
Un tipo que acepta valores NULL puede representar todos los valores de su tipo subyacente más un valor null adicional.A nullable type can represent all values of its underlying type plus an additional null value. Se escribe un tipo que acepta valores NULL T?
, donde T
es el tipo subyacente.A nullable type is written T?
, where T
is the underlying type. Esta sintaxis es una abreviatura de System.Nullable<T>
y las dos formas se pueden usar indistintamente.This syntax is shorthand for System.Nullable<T>
, and the two forms can be used interchangeably.
Un tipo de valor que no acepta valores NULL es un tipo de valor distinto de System.Nullable<T>
y su abreviatura T?
(para cualquier T
), además de cualquier parámetro de tipo restringido para ser un tipo de valor que no acepta valores NULL (es decir, cualquier parámetro de tipo con una struct
restricción).A non-nullable value type conversely is any value type other than System.Nullable<T>
and its shorthand T?
(for any T
), plus any type parameter that is constrained to be a non-nullable value type (that is, any type parameter with a struct
constraint). El System.Nullable<T>
tipo especifica la restricción de tipo de valor para T
(restricciones de parámetro de tipo), lo que significa que el tipo subyacente de un tipo que acepta valores NULL puede ser cualquier tipo de valor que no acepte valores NULL.The System.Nullable<T>
type specifies the value type constraint for T
(Type parameter constraints), which means that the underlying type of a nullable type can be any non-nullable value type. El tipo subyacente de un tipo que acepta valores NULL no puede ser un tipo que acepta valores NULL ni un tipo de referencia.The underlying type of a nullable type cannot be a nullable type or a reference type. Por ejemplo, int??
y string?
son tipos no válidos.For example, int??
and string?
are invalid types.
Una instancia de un tipo que acepta valores NULL T?
tiene dos propiedades públicas de solo lectura:An instance of a nullable type T?
has two public read-only properties:
- Una
HasValue
propiedad de tipobool
AHasValue
property of typebool
- Una
Value
propiedad de tipoT
AValue
property of typeT
Una instancia para la que HasValue
es true se dice que no es NULL.An instance for which HasValue
is true is said to be non-null. Una instancia que no es null contiene un valor conocido y Value
devuelve ese valor.A non-null instance contains a known value and Value
returns that value.
Una instancia para la que HasValue
es false se dice que es NULL.An instance for which HasValue
is false is said to be null. Una instancia null tiene un valor sin definir.A null instance has an undefined value. Al intentar leer la Value
de una instancia null, System.InvalidOperationException
se produce una excepción.Attempting to read the Value
of a null instance causes a System.InvalidOperationException
to be thrown. El proceso de acceso a la Value
propiedad de una instancia que acepta valores NULL se conoce como desencapsulado.The process of accessing the Value
property of a nullable instance is referred to as unwrapping.
Además del constructor predeterminado, todos los tipos que aceptan valores NULL T?
tienen un constructor público que toma un único argumento de tipo T
.In addition to the default constructor, every nullable type T?
has a public constructor that takes a single argument of type T
. Dado un valor x
de tipo T
, una invocación del constructor con el formatoGiven a value x
of type T
, a constructor invocation of the form
new T?(x)
crea una instancia no NULL de T?
para la que la Value
propiedad es x
.creates a non-null instance of T?
for which the Value
property is x
. El proceso de creación de una instancia no NULL de un tipo que acepta valores NULL para un valor determinado se conoce como ajuste.The process of creating a non-null instance of a nullable type for a given value is referred to as wrapping.
Las conversiones implícitas están disponibles desde el null
literal a T?
(conversiones de literales null) y de T
a T?
(conversiones implícitas que aceptan valores NULL).Implicit conversions are available from the null
literal to T?
(Null literal conversions) and from T
to T?
(Implicit nullable conversions).
Tipos de referenciaReference types
Un tipo de referencia es un tipo de clase, un tipo de interfaz, un tipo de matriz o un tipo de delegado.A reference type is a class type, an interface type, an array type, or a delegate type.
reference_type
: class_type
| interface_type
| array_type
| delegate_type
;
class_type
: type_name
| 'object'
| 'dynamic'
| 'string'
;
interface_type
: type_name
;
array_type
: non_array_type rank_specifier+
;
non_array_type
: type
;
rank_specifier
: '[' dim_separator* ']'
;
dim_separator
: ','
;
delegate_type
: type_name
;
Un valor de tipo de referencia es una referencia a una *instancia de del tipo, que se conoce como un objeto _ * * *.A reference type value is a reference to an instance _ of the type, the latter known as an _object**. El valor especial null
es compatible con todos los tipos de referencia e indica la ausencia de una instancia.The special value null
is compatible with all reference types and indicates the absence of an instance.
Tipos de claseClass types
Un tipo de clase define una estructura de datos que contiene miembros de datos (constantes y campos), miembros de función (métodos, propiedades, eventos, indizadores, operadores, constructores de instancias, destructores y constructores estáticos) y tipos anidados.A class type defines a data structure that contains data members (constants and fields), function members (methods, properties, events, indexers, operators, instance constructors, destructors and static constructors), and nested types. Los tipos de clase admiten la herencia, un mecanismo por el que las clases derivadas pueden extender y especializar clases base.Class types support inheritance, a mechanism whereby derived classes can extend and specialize base classes. Las instancias de tipos de clase se crean mediante object_creation_expression s (expresiones de creación de objetos).Instances of class types are created using object_creation_expression s (Object creation expressions).
Los tipos de clase se describen en clases.Class types are described in Classes.
Algunos tipos de clase predefinidos tienen un significado especial en el lenguaje C#, tal y como se describe en la tabla siguiente.Certain predefined class types have special meaning in the C# language, as described in the table below.
Tipo de claseClass type | DescripciónDescription |
---|---|
System.Object |
Última clase base de todos los demás tipos.The ultimate base class of all other types. Vea el tipo de objeto.See The object type. |
System.String |
Tipo de cadena del lenguaje C#.The string type of the C# language. Vea el tipo de cadena.See The string type. |
System.ValueType |
Clase base de todos los tipos de valor.The base class of all value types. Vea el tipo System. ValueType.See The System.ValueType type. |
System.Enum |
La clase base de todos los tipos de enumeración.The base class of all enum types. Vea enumeraciones.See Enums. |
System.Array |
La clase base de todos los tipos de matriz.The base class of all array types. Vea Matrices.See Arrays. |
System.Delegate |
La clase base de todos los tipos de delegado.The base class of all delegate types. Vea delegados.See Delegates. |
System.Exception |
La clase base de todos los tipos de excepción.The base class of all exception types. Vea excepciones.See Exceptions. |
El tipo de objetoThe object type
El object
tipo de clase es la clase base definitiva de todos los demás tipos.The object
class type is the ultimate base class of all other types. Cada tipo de C# deriva directa o indirectamente del object
tipo de clase.Every type in C# directly or indirectly derives from the object
class type.
La palabra clave object
es simplemente un alias para la clase predefinida System.Object
.The keyword object
is simply an alias for the predefined class System.Object
.
Tipo dynamicThe dynamic type
El dynamic
tipo, como object
, puede hacer referencia a cualquier objeto.The dynamic
type, like object
, can reference any object. Cuando se aplican operadores a expresiones de tipo dynamic
, su resolución se aplaza hasta que se ejecuta el programa.When operators are applied to expressions of type dynamic
, their resolution is deferred until the program is run. Por lo tanto, si el operador no se puede aplicar legalmente al objeto al que se hace referencia, no se proporciona ningún error durante la compilación.Thus, if the operator cannot legally be applied to the referenced object, no error is given during compilation. En su lugar, se producirá una excepción cuando se produzca un error en la resolución del operador en tiempo de ejecución.Instead an exception will be thrown when resolution of the operator fails at run-time.
Su finalidad es permitir el enlace dinámico, que se describe en detalle en el enlace dinámico.Its purpose is to allow dynamic binding, which is described in detail in Dynamic binding.
dynamic
se considera idéntico a object
excepto en los siguientes aspectos:dynamic
is considered identical to object
except in the following respects:
- Las operaciones en expresiones de tipo
dynamic
se pueden enlazar dinámicamente (enlace dinámico).Operations on expressions of typedynamic
can be dynamically bound (Dynamic binding). - La inferencia de tipos (inferencia de tipos) preferirá
dynamic
object
si ambas son candidatas.Type inference (Type inference) will preferdynamic
overobject
if both are candidates.
Debido a esta equivalencia, lo siguiente incluye:Because of this equivalence, the following holds:
- Existe una conversión de identidad implícita entre
object
ydynamic
, y entre los tipos construidos que son iguales al reemplazardynamic
porobject
There is an implicit identity conversion betweenobject
anddynamic
, and between constructed types that are the same when replacingdynamic
withobject
- Las conversiones implícitas y explícitas a y desde
object
también se aplican a y desdedynamic
.Implicit and explicit conversions to and fromobject
also apply to and fromdynamic
. - Las firmas de método que son iguales cuando se reemplaza
dynamic
conobject
se consideran la misma firmaMethod signatures that are the same when replacingdynamic
withobject
are considered the same signature dynamic
No se distingue el tipo deobject
en tiempo de ejecución.The typedynamic
is indistinguishable fromobject
at run-time.- Una expresión del tipo
dynamic
se conoce como una expresión dinámica.An expression of the typedynamic
is referred to as a dynamic expression.
Tipo stringThe string type
El string
tipo es un tipo de clase sellado que hereda directamente de object
.The string
type is a sealed class type that inherits directly from object
. Las instancias de la string
clase representan cadenas de caracteres Unicode.Instances of the string
class represent Unicode character strings.
Los valores del string
tipo pueden escribirse como literales de cadena (literales de cadena).Values of the string
type can be written as string literals (String literals).
La palabra clave string
es simplemente un alias para la clase predefinida System.String
.The keyword string
is simply an alias for the predefined class System.String
.
Tipos de interfazInterface types
Una interfaz define un contrato.An interface defines a contract. Una clase o estructura que implementa una interfaz debe adherirse a su contrato.A class or struct that implements an interface must adhere to its contract. Una interfaz puede heredar de varias interfaces base, y una clase o estructura puede implementar varias interfaces.An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.
Los tipos de interfaz se describen en interfaces.Interface types are described in Interfaces.
Tipos de matrizArray types
Una matriz es una estructura de datos que contiene cero o más variables a las que se tiene acceso a través de índices calculados.An array is a data structure that contains zero or more variables which are accessed through computed indices. Las variables contenidas en una matriz, denominadas también elementos de la matriz, son todas del mismo tipo y este tipo se conoce como tipo de elemento de la matriz.The variables contained in an array, also called the elements of the array, are all of the same type, and this type is called the element type of the array.
Los tipos de matriz se describen en matrices.Array types are described in Arrays.
Tipos delegadosDelegate types
Un delegado es una estructura de datos que hace referencia a uno o más métodos.A delegate is a data structure that refers to one or more methods. En el caso de los métodos de instancia, también hace referencia a sus instancias de objeto correspondientes.For instance methods, it also refers to their corresponding object instances.
El equivalente más cercano de un delegado en C o C++ es un puntero a función, pero mientras que un puntero a función solo puede hacer referencia a funciones estáticas, un delegado puede hacer referencia a métodos estáticos y de instancia.The closest equivalent of a delegate in C or C++ is a function pointer, but whereas a function pointer can only reference static functions, a delegate can reference both static and instance methods. En el último caso, el delegado almacena no solo una referencia al punto de entrada del método, sino también una referencia a la instancia de objeto en la que se invoca el método.In the latter case, the delegate stores not only a reference to the method's entry point, but also a reference to the object instance on which to invoke the method.
Los tipos de delegado se describen en delegados.Delegate types are described in Delegates.
Conversiones boxing y unboxingBoxing and unboxing
El concepto de conversión boxing y unboxing es fundamental para el sistema de tipos de C#.The concept of boxing and unboxing is central to C#'s type system. Proporciona un puente entre value_type s y reference_type s permitiendo que cualquier valor de una value_type se convierta al tipo y desde él object
.It provides a bridge between value_type s and reference_type s by permitting any value of a value_type to be converted to and from type object
. Las conversiones boxing y unboxing permiten una vista unificada del sistema de tipos en el que un valor de cualquier tipo se puede tratar en última instancia como un objeto.Boxing and unboxing enables a unified view of the type system wherein a value of any type can ultimately be treated as an object.
Conversiones BoxingBoxing conversions
Una conversión boxing permite convertir implícitamente un value_type en un reference_type.A boxing conversion permits a value_type to be implicitly converted to a reference_type. Existen las siguientes conversiones Boxing:The following boxing conversions exist:
- Desde cualquier value_type al tipo
object
.From any value_type to the typeobject
. - Desde cualquier value_type al tipo
System.ValueType
.From any value_type to the typeSystem.ValueType
. - Desde cualquier non_nullable_value_type a cualquier interface_type implementado por el value_type.From any non_nullable_value_type to any interface_type implemented by the value_type.
- Desde cualquier nullable_type a cualquier interface_type implementado por el tipo subyacente de la nullable_type.From any nullable_type to any interface_type implemented by the underlying type of the nullable_type.
- Desde cualquier enum_type al tipo
System.Enum
.From any enum_type to the typeSystem.Enum
. - Desde cualquier nullable_type con un enum_type subyacente al tipo
System.Enum
.From any nullable_type with an underlying enum_type to the typeSystem.Enum
. - Tenga en cuenta que una conversión implícita de un parámetro de tipo se ejecutará como conversión boxing si en tiempo de ejecución termina la conversión de un tipo de valor a un tipo de referencia (conversiones implícitas que implican parámetros de tipo).Note that an implicit conversion from a type parameter will be executed as a boxing conversion if at run-time it ends up converting from a value type to a reference type (Implicit conversions involving type parameters).
La conversión boxing de un valor de una non_nullable_value_type consiste en asignar una instancia de objeto y copiar el valor de non_nullable_value_type en esa instancia.Boxing a value of a non_nullable_value_type consists of allocating an object instance and copying the non_nullable_value_type value into that instance.
La conversión boxing de un valor de un nullable_type genera una referencia nula si es el null
valor ( HasValue
is false
) o el resultado de desencapsular y convertir en Boxing el valor subyacente en caso contrario.Boxing a value of a nullable_type produces a null reference if it is the null
value (HasValue
is false
), or the result of unwrapping and boxing the underlying value otherwise.
El proceso real de conversión boxing de un valor de un non_nullable_value_type se explica mejor al imaginarse la existencia de una clase de conversión boxing genérica, que se comporta como si se hubiese declarado de la siguiente manera:The actual process of boxing a value of a non_nullable_value_type is best explained by imagining the existence of a generic boxing class, which behaves as if it were declared as follows:
sealed class Box<T>: System.ValueType
{
T value;
public Box(T t) {
value = t;
}
}
La conversión boxing de un valor v
de tipo T
ahora consiste en ejecutar la expresión new Box<T>(v)
y devolver la instancia resultante como un valor de tipo object
.Boxing of a value v
of type T
now consists of executing the expression new Box<T>(v)
, and returning the resulting instance as a value of type object
. Por lo tanto, las instruccionesThus, the statements
int i = 123;
object box = i;
se corresponden conceptualmente conconceptually correspond to
int i = 123;
object box = new Box<int>(i);
Una clase Boxing como Box<T>
la anterior no existe realmente y el tipo dinámico de un valor de conversión boxing no es realmente un tipo de clase.A boxing class like Box<T>
above doesn't actually exist and the dynamic type of a boxed value isn't actually a class type. En su lugar, un valor con conversión boxing de tipo T
tiene el tipo dinámico T
y una comprobación de tipos dinámicos mediante el is
operador puede simplemente hacer referencia al tipo T
.Instead, a boxed value of type T
has the dynamic type T
, and a dynamic type check using the is
operator can simply reference type T
. Por ejemplo,For example,
int i = 123;
object box = i;
if (box is int) {
Console.Write("Box contains an int");
}
dará como resultado la cadena " Box contains an int
" en la consola.will output the string "Box contains an int
" on the console.
Una conversión boxing implica que se realice una copia del valor al que se va a aplicar la conversión boxing.A boxing conversion implies making a copy of the value being boxed. Esto es diferente de la conversión de un reference_type al tipo object
, en el que el valor sigue haciendo referencia a la misma instancia y simplemente se considera como el tipo menos derivado object
.This is different from a conversion of a reference_type to type object
, in which the value continues to reference the same instance and simply is regarded as the less derived type object
. Por ejemplo, dada la declaraciónFor example, given the declaration
struct Point
{
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
las instrucciones siguientesthe following statements
Point p = new Point(10, 10);
object box = p;
p.x = 20;
Console.Write(((Point)box).x);
dará como resultado el valor 10 en la consola de porque la operación de conversión boxing implícita que se produce en la asignación de p
a box
hace que se copie el valor de p
.will output the value 10 on the console because the implicit boxing operation that occurs in the assignment of p
to box
causes the value of p
to be copied. Si Point
se hubiera declarado class
en su lugar, el valor 20 sería Output porque p
y box
haría referencia a la misma instancia.Had Point
been declared a class
instead, the value 20 would be output because p
and box
would reference the same instance.
Conversiones unboxingUnboxing conversions
Una conversión unboxing permite convertir un reference_type explícitamente en un value_type.An unboxing conversion permits a reference_type to be explicitly converted to a value_type. Existen las siguientes conversiones unboxing:The following unboxing conversions exist:
- Del tipo
object
a cualquier value_type.From the typeobject
to any value_type. - Del tipo
System.ValueType
a cualquier value_type.From the typeSystem.ValueType
to any value_type. - Desde cualquier interface_type a cualquier non_nullable_value_type que implementa la interface_type.From any interface_type to any non_nullable_value_type that implements the interface_type.
- Desde cualquier interface_type a cualquier nullable_type cuyo tipo subyacente implementa la interface_type.From any interface_type to any nullable_type whose underlying type implements the interface_type.
- Del tipo
System.Enum
a cualquier enum_type.From the typeSystem.Enum
to any enum_type. - Del tipo
System.Enum
a cualquier nullable_type con un enum_type subyacente.From the typeSystem.Enum
to any nullable_type with an underlying enum_type. - Tenga en cuenta que una conversión explícita a un parámetro de tipo se ejecutará como una conversión unboxing si en tiempo de ejecución termina la conversión de un tipo de referencia a un tipo de valor (conversiones dinámicas explícitas).Note that an explicit conversion to a type parameter will be executed as an unboxing conversion if at run-time it ends up converting from a reference type to a value type (Explicit dynamic conversions).
Una operación de conversión unboxing a un non_nullable_value_type consiste en comprobar primero que la instancia de objeto es un valor de conversión boxing del non_nullable_value_type especificado y, a continuación, copiar el valor fuera de la instancia.An unboxing operation to a non_nullable_value_type consists of first checking that the object instance is a boxed value of the given non_nullable_value_type, and then copying the value out of the instance.
La conversión unboxing a un nullable_type genera el valor null del nullable_type si el operando de origen es null
, o el resultado ajustado de la conversión unboxing de la instancia de objeto en el tipo subyacente de la nullable_type en caso contrario.Unboxing to a nullable_type produces the null value of the nullable_type if the source operand is null
, or the wrapped result of unboxing the object instance to the underlying type of the nullable_type otherwise.
Al hacer referencia a la clase de conversión boxing imaginaria descrita en la sección anterior, una conversión unboxing de un objeto box
en un value_type T
consiste en ejecutar la expresión ((Box<T>)box).value
.Referring to the imaginary boxing class described in the previous section, an unboxing conversion of an object box
to a value_type T
consists of executing the expression ((Box<T>)box).value
. Por lo tanto, las instruccionesThus, the statements
object box = 123;
int i = (int)box;
se corresponden conceptualmente conconceptually correspond to
object box = new Box<int>(123);
int i = ((Box<int>)box).value;
Para que una conversión unboxing a una non_nullable_value_type determinada se realice correctamente en tiempo de ejecución, el valor del operando de origen debe ser una referencia a un valor de conversión boxing de ese non_nullable_value_type.For an unboxing conversion to a given non_nullable_value_type to succeed at run-time, the value of the source operand must be a reference to a boxed value of that non_nullable_value_type. Si el operando de origen es null
, System.NullReferenceException
se produce una excepción.If the source operand is null
, a System.NullReferenceException
is thrown. Si el operando de origen es una referencia a un objeto incompatible, System.InvalidCastException
se produce una excepción.If the source operand is a reference to an incompatible object, a System.InvalidCastException
is thrown.
Para que una conversión unboxing a una nullable_type determinada se realice correctamente en tiempo de ejecución, el valor del operando de origen debe ser null
o una referencia a un valor de conversión boxing del non_nullable_value_type subyacente de la nullable_type.For an unboxing conversion to a given nullable_type to succeed at run-time, the value of the source operand must be either null
or a reference to a boxed value of the underlying non_nullable_value_type of the nullable_type. Si el operando de origen es una referencia a un objeto incompatible, System.InvalidCastException
se produce una excepción.If the source operand is a reference to an incompatible object, a System.InvalidCastException
is thrown.
Tipos construidosConstructed types
Una declaración de tipo genérico, por sí sola, denota un *tipo genérico sin enlazar, que se usa como "Blueprint" para formar muchos tipos diferentes, por medio de la aplicación de argumentos de tipo.A generic type declaration, by itself, denotes an unbound generic type _ that is used as a "blueprint" to form many different types, by way of applying _type arguments*_. Los argumentos de tipo se escriben entre corchetes angulares ( <
y >
) inmediatamente después del nombre del tipo genérico.The type arguments are written within angle brackets (<
and >
) immediately following the name of the generic type. Un tipo que incluye al menos un argumento de tipo se denomina tipo construido.A type that includes at least one type argument is called a constructed type. Un tipo construido se puede usar en la mayoría de los lugares del lenguaje en el que puede aparecer un nombre de tipo.A constructed type can be used in most places in the language in which a type name can appear. Un tipo genérico sin enlazar solo se puede usar dentro de un _typeof_expression * (el operador typeof).An unbound generic type can only be used within a _typeof_expression* (The typeof operator).
Los tipos construidos también se pueden usar en expresiones como nombres simples (nombres simples) o al obtener acceso a un miembro (acceso a miembros).Constructed types can also be used in expressions as simple names (Simple names) or when accessing a member (Member access).
Cuando se evalúa un namespace_or_type_name , solo se tienen en cuenta los tipos genéricos con el número correcto de parámetros de tipo.When a namespace_or_type_name is evaluated, only generic types with the correct number of type parameters are considered. Por lo tanto, es posible usar el mismo identificador para identificar distintos tipos, siempre que los tipos tengan distintos números de parámetros de tipo.Thus, it is possible to use the same identifier to identify different types, as long as the types have different numbers of type parameters. Esto resulta útil cuando se combinan clases genéricas y no genéricas en el mismo programa:This is useful when mixing generic and non-generic classes in the same program:
namespace Widgets
{
class Queue {...}
class Queue<TElement> {...}
}
namespace MyApplication
{
using Widgets;
class X
{
Queue q1; // Non-generic Widgets.Queue
Queue<int> q2; // Generic Widgets.Queue
}
}
Un type_name podría identificar un tipo construido aunque no especifique directamente los parámetros de tipo.A type_name might identify a constructed type even though it doesn't specify type parameters directly. Esto puede ocurrir cuando un tipo está anidado dentro de una declaración de clase genérica y el tipo de instancia de la declaración contenedora se usa implícitamente para la búsqueda de nombres (tipos anidados en clases genéricas):This can occur where a type is nested within a generic class declaration, and the instance type of the containing declaration is implicitly used for name lookup (Nested types in generic classes):
class Outer<T>
{
public class Inner {...}
public Inner i; // Type of i is Outer<T>.Inner
}
En código no seguro, no se puede usar un tipo construido como unmanaged_type (tipos de puntero).In unsafe code, a constructed type cannot be used as an unmanaged_type (Pointer types).
Argumentos de tipoType arguments
Cada argumento de una lista de argumentos de tipo es simplemente un tipo.Each argument in a type argument list is simply a type.
type_argument_list
: '<' type_arguments '>'
;
type_arguments
: type_argument (',' type_argument)*
;
type_argument
: type
;
En el código no seguro (código no seguro), un type_argument no puede ser un tipo de puntero.In unsafe code (Unsafe code), a type_argument may not be a pointer type. Cada argumento de tipo debe satisfacer las restricciones en el parámetro de tipo correspondiente (restricciones de parámetro de tipo).Each type argument must satisfy any constraints on the corresponding type parameter (Type parameter constraints).
Tipos abiertos y cerradosOpen and closed types
Todos los tipos se pueden clasificar como * tipos abiertos _ o _ tipos cerrados *.All types can be classified as either open types _ or _closed types**. Un tipo abierto es un tipo que implica parámetros de tipo.An open type is a type that involves type parameters. Más concretamente:More specifically:
- Un parámetro de tipo define un tipo abierto.A type parameter defines an open type.
- Un tipo de matriz es un tipo abierto solo si su tipo de elemento es un tipo abierto.An array type is an open type if and only if its element type is an open type.
- Un tipo construido es un tipo abierto solo si uno o varios de sus argumentos de tipo es un tipo abierto.A constructed type is an open type if and only if one or more of its type arguments is an open type. Un tipo anidado construido es un tipo abierto si y solo si uno o varios de sus argumentos de tipo o los argumentos de tipo de sus tipos contenedores es un tipo abierto.A constructed nested type is an open type if and only if one or more of its type arguments or the type arguments of its containing type(s) is an open type.
Un tipo cerrado es un tipo que no es un tipo abierto.A closed type is a type that is not an open type.
En tiempo de ejecución, todo el código dentro de una declaración de tipos genéricos se ejecuta en el contexto de un tipo construido cerrado que se creó mediante la aplicación de argumentos de tipo a la declaración genérica.At run-time, all of the code within a generic type declaration is executed in the context of a closed constructed type that was created by applying type arguments to the generic declaration. Cada parámetro de tipo dentro del tipo genérico se enlaza a un tipo en tiempo de ejecución determinado.Each type parameter within the generic type is bound to a particular run-time type. El procesamiento en tiempo de ejecución de todas las instrucciones y expresiones siempre se produce con tipos cerrados y los tipos abiertos solo se producen durante el procesamiento en tiempo de compilación.The run-time processing of all statements and expressions always occurs with closed types, and open types occur only during compile-time processing.
Cada tipo construido cerrado tiene su propio conjunto de variables estáticas, que no se comparten con otros tipos construidos cerrados.Each closed constructed type has its own set of static variables, which are not shared with any other closed constructed types. Puesto que no existe un tipo abierto en tiempo de ejecución, no hay variables estáticas asociadas a un tipo abierto.Since an open type does not exist at run-time, there are no static variables associated with an open type. Dos tipos construidos cerrados son del mismo tipo si se construyen a partir del mismo tipo genérico sin enlazar y sus argumentos de tipo correspondientes son del mismo tipo.Two closed constructed types are the same type if they are constructed from the same unbound generic type, and their corresponding type arguments are the same type.
Tipos enlazados y sin enlazarBound and unbound types
El término *tipo sin enlazar _ hace referencia a un tipo no genérico o a un tipo genérico sin enlazar.The term *unbound type _ refers to a non-generic type or an unbound generic type. El término _ Bound Type* hace referencia a un tipo no genérico o a un tipo construido.The term _ bound type* refers to a non-generic type or a constructed type.
Un tipo sin enlazar hace referencia a la entidad declarada por una declaración de tipos.An unbound type refers to the entity declared by a type declaration. Un tipo genérico sin enlazar no es en sí mismo un tipo y no se puede usar como el tipo de una variable, argumento o valor devuelto, o como un tipo base.An unbound generic type is not itself a type, and cannot be used as the type of a variable, argument or return value, or as a base type. La única construcción en la que se puede hacer referencia a un tipo genérico sin enlazar es la typeof
expresión (el operador typeof).The only construct in which an unbound generic type can be referenced is the typeof
expression (The typeof operator).
Satisfacer restriccionesSatisfying constraints
Siempre que se hace referencia a un tipo construido o a un método genérico, los argumentos de tipo proporcionados se comprueban con las restricciones de parámetro de tipo declaradas en el tipo o método genérico (restricciones de parámetro de tipo).Whenever a constructed type or generic method is referenced, the supplied type arguments are checked against the type parameter constraints declared on the generic type or method (Type parameter constraints). Para cada where
cláusula, el argumento de tipo A
que se corresponde con el parámetro de tipo con nombre se compara con cada restricción de la manera siguiente:For each where
clause, the type argument A
that corresponds to the named type parameter is checked against each constraint as follows:
- Si la restricción es un tipo de clase, un tipo de interfaz o un parámetro de tipo, permita
C
representar esa restricción con los argumentos de tipo proporcionados que se sustituyen por los parámetros de tipo que aparecen en la restricción.If the constraint is a class type, an interface type, or a type parameter, letC
represent that constraint with the supplied type arguments substituted for any type parameters that appear in the constraint. Para satisfacer la restricción, debe ser el caso de que el tipoA
se pueda convertir al tipoC
mediante una de las siguientes acciones:To satisfy the constraint, it must be the case that typeA
is convertible to typeC
by one of the following:- Una conversión de identidad (conversión de identidad)An identity conversion (Identity conversion)
- Una conversión de referencia implícita (conversiones de referencia implícita)An implicit reference conversion (Implicit reference conversions)
- Una conversión boxing (conversiones boxing), siempre que el tipo a sea un tipo de valor que no acepte valores NULL.A boxing conversion (Boxing conversions), provided that type A is a non-nullable value type.
- Referencia implícita, conversión boxing o conversión de parámetros de tipo de un parámetro de tipo
A
aC
.An implicit reference, boxing or type parameter conversion from a type parameterA
toC
.
- Si la restricción es la restricción de tipo de referencia (
class
), el tipoA
debe cumplir uno de los siguientes elementos:If the constraint is the reference type constraint (class
), the typeA
must satisfy one of the following:A
es un tipo de interfaz, tipo de clase, tipo de delegado o tipo de matriz.A
is an interface type, class type, delegate type or array type. Tenga en cuenta queSystem.ValueType
ySystem.Enum
son tipos de referencia que satisfacen esta restricción.Note thatSystem.ValueType
andSystem.Enum
are reference types that satisfy this constraint.A
es un parámetro de tipo que se sabe que es un tipo de referencia (restricciones de parámetro de tipo).A
is a type parameter that is known to be a reference type (Type parameter constraints).
- Si la restricción es la restricción de tipo de valor (
struct
), el tipoA
debe cumplir uno de los siguientes elementos:If the constraint is the value type constraint (struct
), the typeA
must satisfy one of the following:A
es un tipo de estructura o un tipo de enumeración, pero no un tipo que acepta valores NULL.A
is a struct type or enum type, but not a nullable type. Tenga en cuenta queSystem.ValueType
ySystem.Enum
son tipos de referencia que no cumplen esta restricción.Note thatSystem.ValueType
andSystem.Enum
are reference types that do not satisfy this constraint.A
es un parámetro de tipo que tiene la restricción de tipo de valor (restricciones de parámetro de tipo).A
is a type parameter having the value type constraint (Type parameter constraints).
- Si la restricción es la restricción del constructor
new()
, el tipoA
no debe serabstract
y debe tener un constructor sin parámetros público.If the constraint is the constructor constraintnew()
, the typeA
must not beabstract
and must have a public parameterless constructor. Esto se cumple si se cumple una de las siguientes condiciones:This is satisfied if one of the following is true:A
es un tipo de valor, ya que todos los tipos de valor tienen un constructor predeterminado público (constructores predeterminados).A
is a value type, since all value types have a public default constructor (Default constructors).A
es un parámetro de tipo que tiene la restricción de constructor (restricciones de parámetro de tipo).A
is a type parameter having the constructor constraint (Type parameter constraints).A
es un parámetro de tipo que tiene la restricción de tipo de valor (restricciones de parámetro de tipo).A
is a type parameter having the value type constraint (Type parameter constraints).A
es una clase que no esabstract
y contiene un constructor declarado explícitamentepublic
sin parámetros.A
is a class that is notabstract
and contains an explicitly declaredpublic
constructor with no parameters.A
no esabstract
y tiene un constructor predeterminado (constructores predeterminados).A
is notabstract
and has a default constructor (Default constructors).
Se produce un error en tiempo de compilación si los argumentos de tipo especificados no satisfacen una o varias restricciones de un parámetro de tipo.A compile-time error occurs if one or more of a type parameter's constraints are not satisfied by the given type arguments.
Dado que los parámetros de tipo no se heredan, las restricciones nunca se heredan.Since type parameters are not inherited, constraints are never inherited either. En el ejemplo siguiente, D
debe especificar la restricción en su parámetro de tipo T
para que T
cumpla la restricción impuesta por la clase base B<T>
.In the example below, D
needs to specify the constraint on its type parameter T
so that T
satisfies the constraint imposed by the base class B<T>
. En cambio, E
la clase no necesita especificar una restricción, porque List<T>
implementa IEnumerable
para any T
.In contrast, class E
need not specify a constraint, because List<T>
implements IEnumerable
for any T
.
class B<T> where T: IEnumerable {...}
class D<T>: B<T> where T: IEnumerable {...}
class E<T>: B<List<T>> {...}
Parámetros de tipoType parameters
Un parámetro de tipo es un identificador que designa un tipo de valor o un tipo de referencia al que está enlazado el parámetro en tiempo de ejecución.A type parameter is an identifier designating a value type or reference type that the parameter is bound to at run-time.
type_parameter
: identifier
;
Dado que se pueden crear instancias de un parámetro de tipo con muchos argumentos de tipo reales diferentes, los parámetros de tipo tienen operaciones y restricciones ligeramente diferentes a las de otros tipos.Since a type parameter can be instantiated with many different actual type arguments, type parameters have slightly different operations and restrictions than other types. Entre ellos, se incluye:These include:
- Un parámetro de tipo no se puede usar directamente para declarar una clase base (clase base) o una interfaz (listas de parámetros de tipo variante).A type parameter cannot be used directly to declare a base class (Base class) or interface (Variant type parameter lists).
- Las reglas para la búsqueda de miembros en parámetros de tipo dependen de las restricciones, si las hay, que se aplican al parámetro de tipo.The rules for member lookup on type parameters depend on the constraints, if any, applied to the type parameter. Se detallan en la búsqueda de miembros.They are detailed in Member lookup.
- Las conversiones disponibles para un parámetro de tipo dependen de las restricciones, si las hay, que se aplican al parámetro de tipo.The available conversions for a type parameter depend on the constraints, if any, applied to the type parameter. Se detallan en conversiones implícitas que implican parámetros de tipo y conversiones dinámicas explícitas.They are detailed in Implicit conversions involving type parameters and Explicit dynamic conversions.
- El literal
null
no se puede convertir en un tipo proporcionado por un parámetro de tipo, excepto si se sabe que el parámetro de tipo es un tipo de referencia (conversiones implícitas que implican parámetros de tipo).The literalnull
cannot be converted to a type given by a type parameter, except if the type parameter is known to be a reference type (Implicit conversions involving type parameters). Sin embargo,default
en su lugar se puede utilizar una expresión (expresiones de valor predeterminado).However, adefault
expression (Default value expressions) can be used instead. Además, un valor con un tipo proporcionado por un parámetro de tipo puede compararse connull
mediante==
y!=
(operadores de igualdad de tipos dereferencia), a menos que el parámetro de tipo tenga la restricción de tipo de valor.In addition, a value with a type given by a type parameter can be compared withnull
using==
and!=
(Reference type equality operators) unless the type parameter has the value type constraint. - Una
new
expresión (expresiones de creación de objetos) solo se puede utilizar con un parámetro de tipo si el parámetro de tipo está restringido por un constructor_constraint o la restricción de tipo de valor (restricciones de parámetro de tipo).Anew
expression (Object creation expressions) can only be used with a type parameter if the type parameter is constrained by a constructor_constraint or the value type constraint (Type parameter constraints). - Un parámetro de tipo no se puede usar en ningún lugar dentro de un atributo.A type parameter cannot be used anywhere within an attribute.
- No se puede usar un parámetro de tipo en un acceso de miembro (acceso a miembros) o nombre de tipo (espacio de nombresy nombres de tipo) para identificar un miembro estático o un tipo anidado.A type parameter cannot be used in a member access (Member access) or type name (Namespace and type names) to identify a static member or a nested type.
- En código no seguro, no se puede usar un parámetro de tipo como unmanaged_type (tipos de puntero).In unsafe code, a type parameter cannot be used as an unmanaged_type (Pointer types).
Como tipo, los parámetros de tipo son únicamente una construcción en tiempo de compilación.As a type, type parameters are purely a compile-time construct. En tiempo de ejecución, cada parámetro de tipo se enlaza a un tipo en tiempo de ejecución que se especificó proporcionando un argumento de tipo a la declaración de tipos genéricos.At run-time, each type parameter is bound to a run-time type that was specified by supplying a type argument to the generic type declaration. Por lo tanto, el tipo de una variable declarada con un parámetro de tipo, en tiempo de ejecución, será un tipo construido cerrado (tipos abiertos y cerrados).Thus, the type of a variable declared with a type parameter will, at run-time, be a closed constructed type (Open and closed types). La ejecución en tiempo de ejecución de todas las instrucciones y expresiones que impliquen parámetros de tipo usa el tipo real que se proporcionó como argumento de tipo para ese parámetro.The run-time execution of all statements and expressions involving type parameters uses the actual type that was supplied as the type argument for that parameter.
Tipos de árbol de expresiónExpression tree types
*Los árboles de expresión _ permiten representar expresiones lambda como estructuras de datos en lugar de código ejecutable.*Expression trees _ permit lambda expressions to be represented as data structures instead of executable code. Los árboles de expresión son valores de _ tipos de árbol de expresión* del formulario System.Linq.Expressions.Expression<D>
, donde D
es cualquier tipo de delegado.Expression trees are values of _ expression tree types* of the form System.Linq.Expressions.Expression<D>
, where D
is any delegate type. En el resto de esta especificación, haremos referencia a estos tipos con la abreviatura Expression<D>
.For the remainder of this specification we will refer to these types using the shorthand Expression<D>
.
Si existe una conversión de una expresión lambda a un tipo de delegado D
, también existe una conversión al tipo de árbol de expresión Expression<D>
.If a conversion exists from a lambda expression to a delegate type D
, a conversion also exists to the expression tree type Expression<D>
. Mientras que la conversión de una expresión lambda a un tipo de delegado genera un delegado que hace referencia al código ejecutable de la expresión lambda, la conversión a un tipo de árbol de expresión crea una representación de árbol de expresión de la expresión lambda.Whereas the conversion of a lambda expression to a delegate type generates a delegate that references executable code for the lambda expression, conversion to an expression tree type creates an expression tree representation of the lambda expression.
Los árboles de expresión son representaciones eficaces de datos en memoria de expresiones lambda y hacen que la estructura de la expresión lambda sea transparente y explícita.Expression trees are efficient in-memory data representations of lambda expressions and make the structure of the lambda expression transparent and explicit.
Al igual que un tipo D
de delegado, Expression<D>
se dice que tiene tipos de parámetro y de valor devuelto, que son los mismos que los de D
.Just like a delegate type D
, Expression<D>
is said to have parameter and return types, which are the same as those of D
.
En el ejemplo siguiente se representa una expresión lambda como código ejecutable y como un árbol de expresión.The following example represents a lambda expression both as executable code and as an expression tree. Dado que existe una conversión a Func<int,int>
, también existe una conversión a Expression<Func<int,int>>
:Because a conversion exists to Func<int,int>
, a conversion also exists to Expression<Func<int,int>>
:
Func<int,int> del = x => x + 1; // Code
Expression<Func<int,int>> exp = x => x + 1; // Data
Después de estas asignaciones, el delegado del
hace referencia a un método que devuelve x + 1
y el árbol de expresión exp
hace referencia a una estructura de datos que describe la expresión x => x + 1
.Following these assignments, the delegate del
references a method that returns x + 1
, and the expression tree exp
references a data structure that describes the expression x => x + 1
.
La definición exacta del tipo genérico, Expression<D>
así como las reglas precisas para construir un árbol de expresión cuando una expresión lambda se convierte en un tipo de árbol de expresión, está fuera del ámbito de esta especificación.The exact definition of the generic type Expression<D>
as well as the precise rules for constructing an expression tree when a lambda expression is converted to an expression tree type, are both outside the scope of this specification.
Es importante hacer dos cosas:Two things are important to make explicit:
No todas las expresiones lambda se pueden convertir en árboles de expresión.Not all lambda expressions can be converted to expression trees. Por ejemplo, las expresiones lambda con cuerpos de instrucciones y expresiones lambda que contienen expresiones de asignación no se pueden representar.For instance, lambda expressions with statement bodies, and lambda expressions containing assignment expressions cannot be represented. En estos casos, todavía existe una conversión, pero se producirá un error en tiempo de compilación.In these cases, a conversion still exists, but will fail at compile-time. Estas excepciones se detallan en conversiones de funciones anónimas.These exceptions are detailed in Anonymous function conversions.
Expression<D>
proporciona un métodoCompile
de instancia que genera un delegado de tipoD
:Expression<D>
offers an instance methodCompile
which produces a delegate of typeD
:Func<int,int> del2 = exp.Compile();
Al invocar este delegado se produce el código representado por el árbol de expresión que se va a ejecutar.Invoking this delegate causes the code represented by the expression tree to be executed. Por lo tanto, dado que las definiciones anteriores, del y DEL2 son equivalentes, y las dos instrucciones siguientes tendrán el mismo efecto:Thus, given the definitions above, del and del2 are equivalent, and the following two statements will have the same effect:
int i1 = del(1); int i2 = del2(1);
Después de ejecutar este código,
i1
yi2
ambos tendrán el valor2
.After executing this code,i1
andi2
will both have the value2
.