Tipos de referencia integrados (referencia de C#)Built-in reference types (C# reference)

C# tiene un número de tipos de referencia integrados.C# has a number of built-in reference types. Tienen palabras clave u operadores que son sinónimos para un tipo en la biblioteca de .NET.They have keywords or operators that are synonyms for a type in the .NET library.

Tipo objectThe object type

El tipo object es un alias de System.Object en .NET.The object type is an alias for System.Object in .NET. En el sistema de tipos unificado de C#, todos los tipos, los predefinidos y los definidos por el usuario, los tipos de referencia y los tipos de valores, heredan directa o indirectamente de System.Object.In the unified type system of C#, all types, predefined and user-defined, reference types and value types, inherit directly or indirectly from System.Object. Puede asignar valores de cualquier tipo a las variables de tipo object.You can assign values of any type to variables of type object. Cualquier variable object puede asignarse a su valor predeterminado con el literal null.Any object variable can be assigned to its default value using the literal null. Cuando una variable de un tipo de valor se convierte en objeto, se dice que se aplica la conversión boxing.When a variable of a value type is converted to object, it is said to be boxed. Cuando una variable de tipo de objeto se convierte en un tipo de valor, se dice que se aplica la conversión unboxing.When a variable of type object is converted to a value type, it is said to be unboxed. Para obtener más información, vea Conversión boxing y unboxing.For more information, see Boxing and Unboxing.

Tipo stringThe string type

El tipo string representa una secuencia de cero o más caracteres Unicode.The string type represents a sequence of zero or more Unicode characters. string es un alias de System.String en .NET.string is an alias for System.String in .NET.

Aunque string es un tipo de referencia, se definen los operadores de igualdad == y != para comparar los valores de los objetos string, no las referencias.Although string is a reference type, the equality operators == and != are defined to compare the values of string objects, not references. Esto hace que las pruebas de igualdad entre cadenas sean más intuitivas.This makes testing for string equality more intuitive. Por ejemplo:For example:

string a = "hello";
string b = "h";
// Append to contents of 'b'
b += "ello";
Console.WriteLine(a == b);
Console.WriteLine(object.ReferenceEquals(a, b));

Se muestra "True" y luego "False" porque el contenido de las cadenas es equivalente, pero a y b no hacen referencia a la misma instancia de cadena.This displays "True" and then "False" because the content of the strings are equivalent, but a and b do not refer to the same string instance.

El operador + concatena cadenas:The + operator concatenates strings:

string a = "good " + "morning";

Crea un objeto de cadena que contiene "good morning".This creates a string object that contains "good morning".

Las cadenas son inmutables: el contenido de un objeto de cadena no se puede modificar una vez creado el objeto, aunque la sintaxis parezca indicar que se puede hacer.Strings are immutable--the contents of a string object cannot be changed after the object is created, although the syntax makes it appear as if you can do this. Por ejemplo, al escribir este código, el compilador crea en realidad otro objeto de cadena para almacenar la nueva secuencia de caracteres, y este nuevo objeto se asigna a b.For example, when you write this code, the compiler actually creates a new string object to hold the new sequence of characters, and that new object is assigned to b. La memoria que se había asignado para b (cuando contiene la cadena "h") es entonces apto para la recolección de elementos.The memory that had been allocated for b (when it contained the string "h") is then eligible for garbage collection.

string b = "h";
b += "ello";

El operador [] puede usarse para acceso de solo lectura a determinados caracteres de una string.The [] operator can be used for readonly access to individual characters of a string. Los valores válidos comienzan por 0 y deben ser menores que la longitud de la string:Valid values start at 0 and must be less than the length of the string:

string str = "test";
char x = str[2];  // x = 's';

De igual manera, el operador [] también puede usarse para recorrer en iteración cada carácter en string:In similar fashion, the [] operator can also be used for iterating over each character in a string:

string str = "test";

for (int i = 0; i < str.Length; i++)
{
  Console.Write(str[i] + " ");
}
// Output: t e s t

Los literales de cadena son del tipo string y se pueden escribir de dos formas, entre comillas y entre @.String literals are of type string and can be written in two forms, quoted and @-quoted. Los literales de cadena se incluyen entre comillas dobles ("):Quoted string literals are enclosed in double quotation marks ("):

"good morning"  // a string literal

Los literales de cadena pueden contener cualquier literal de carácter.String literals can contain any character literal. Se incluyen secuencias de escape.Escape sequences are included. En el ejemplo siguiente se usa una secuencia de escape \\ para la barra diagonal inversa, \u0066 para la letra f y \n para la nueva línea.The following example uses escape sequence \\ for backslash, \u0066 for the letter f, and \n for newline.

string a = "\\\u0066\n F";
Console.WriteLine(a);
\\ Output:
\\ \f
\\  F

Nota

El código de escape \udddd (donde dddd es un número de cuatro dígitos) representa el carácter Unicode U+dddd.The escape code \udddd (where dddd is a four-digit number) represents the Unicode character U+dddd. También se reconocen los códigos de escape Unicode de 8 dígitos: \Udddddddd.Eight-digit Unicode escape codes are also recognized: \Udddddddd.

Los literales de cadena textual empiezan por @ y también se incluyen entre comillas dobles.Verbatim string literals start with @ and are also enclosed in double quotation marks. Por ejemplo:For example:

@"good morning"  // a string literal

La ventaja de las cadenas textuales es que las secuencias de escape no se procesan, lo que facilita la escritura de, por ejemplo, un nombre de archivo Windows completo:The advantage of verbatim strings is that escape sequences are not processed, which makes it easy to write, for example, a fully qualified Windows file name:

@"c:\Docs\Source\a.txt"  // rather than "c:\\Docs\\Source\\a.txt"

Para incluir un signo de comillas dobles en una cadena @-quoted, duplíquelo:To include a double quotation mark in an @-quoted string, double it:

@"""Ahoy!"" cried the captain." // "Ahoy!" cried the captain.

Tipo delegateThe delegate type

La declaración de un tipo delegado es similar a una firma de método.The declaration of a delegate type is similar to a method signature. Tiene un valor devuelto y un número cualquiera de parámetros de cualquier tipo:It has a return value and any number of parameters of any type:

public delegate void MessageDelegate(string message);
public delegate int AnotherDelegate(MyType m, long num);

En. NET, los tipos System.Action y System.Func proporcionan definiciones genéricas para muchos delegados comunes.In .NET, System.Action and System.Func types provide generic definitions for many common delegates. Es probable que no sea necesario definir nuevos tipos delegados personalizados.You likely don't need to define new custom delegate types. En su lugar, puede crear instancias de los tipos genéricos proporcionados.Instead, you can create instantiations of the provided generic types.

Un delegate es un tipo de referencia que puede usarse para encapsular un método con nombre o anónimo.A delegate is a reference type that can be used to encapsulate a named or an anonymous method. Los delegados son similares a los punteros de función en C++; pero son más seguros y proporcionan mayor seguridad de tipos.Delegates are similar to function pointers in C++; however, delegates are type-safe and secure. Para las aplicaciones de delegados, vea Delegados y Delegados genéricos.For applications of delegates, see Delegates and Generic Delegates. Los delegados son la base de los eventos.Delegates are the basis for Events. Se pueden crear instancias de un delegado asociándolo a un método con nombre o anónimo.A delegate can be instantiated by associating it either with a named or anonymous method.

Para crear instancias del delegado debe usarse un método o una expresión lambda que tenga un tipo de valor devuelto y parámetros de entrada compatibles.The delegate must be instantiated with a method or lambda expression that has a compatible return type and input parameters. Para obtener más información sobre el grado de variación permitida en la firma de método, vea Varianza en delegados.For more information on the degree of variance that is allowed in the method signature, see Variance in Delegates. Para el uso con métodos anónimos, el delegado y el código que se van a asociar se declaran juntos.For use with anonymous methods, the delegate and the code to be associated with it are declared together.

Tipo dynamicThe dynamic type

El tipo dynamic indica el uso de la variable y las referencias a su comprobación de tipos en el tiempo de compilación de omisión de miembros.The dynamic type indicates that use of the variable and references to its members bypass compile-time type checking. En su lugar, se resuelven estas operaciones en tiempo de ejecución.Instead, these operations are resolved at run time. El tipo dynamic simplifica el acceso a las API de COM como las API de automatización de Office, a API dinámicas como las bibliotecas de IronPython, y a Document Object Model (DOM) HTML.The dynamic type simplifies access to COM APIs such as the Office Automation APIs, to dynamic APIs such as IronPython libraries, and to the HTML Document Object Model (DOM).

El tipo dynamic se comporta como el tipo object en la mayoría de las circunstancias.Type dynamic behaves like type object in most circumstances. En concreto, se puede convertir cualquier expresión no NULL para el tipo dynamic.In particular, any non-null expression can be converted to the dynamic type. El tipo dynamic se diferencia de object en que el compilador no resuelve o no comprueba el tipo de las operaciones que contienen expresiones de tipo dynamic.The dynamic type differs from object in that operations that contain expressions of type dynamic are not resolved or type checked by the compiler. El compilador empaqueta información sobre la operación y esa información se usa después para evaluar la operación en tiempo de ejecución.The compiler packages together information about the operation, and that information is later used to evaluate the operation at run time. Como parte del proceso, las variables de tipo dynamic están compiladas en las variables de tipo object.As part of the process, variables of type dynamic are compiled into variables of type object. Por consiguiente, el tipo dynamic solo existe en tiempo de compilación, no en tiempo de ejecución.Therefore, type dynamic exists only at compile time, not at run time.

En el siguiente ejemplo se contrasta una variable de tipo dynamic con una variable de tipo object.The following example contrasts a variable of type dynamic to a variable of type object. Para comprobar el tipo de cada variable en tiempo de compilación, coloque el puntero del mouse sobre dyn u obj en las instrucciones WriteLine.To verify the type of each variable at compile time, place the mouse pointer over dyn or obj in the WriteLine statements. Copie el código siguiente en un editor donde IntelliSense esté disponible.Copy the following code into an editor where IntelliSense is available. IntelliSense muestra dynamic para dyn y object para obj.IntelliSense shows dynamic for dyn and object for obj.

class Program
{
    static void Main(string[] args)
    {
        dynamic dyn = 1;
        object obj = 1;

        // Rest the mouse pointer over dyn and obj to see their
        // types at compile time.
        System.Console.WriteLine(dyn.GetType());
        System.Console.WriteLine(obj.GetType());
    }
}

Las instrucciones WriteLine muestran los tipos en tiempo de ejecución de dyn y obj.The WriteLine statements display the run-time types of dyn and obj. En ese punto, ambos tienen el mismo tipo, entero.At that point, both have the same type, integer. Se produce el siguiente resultado:The following output is produced:

System.Int32
System.Int32

Para ver la diferencia entre dyn y obj en tiempo de compilación, agregue las dos líneas siguientes entre las declaraciones y las instrucciones WriteLine en el ejemplo anterior.To see the difference between dyn and obj at compile time, add the following two lines between the declarations and the WriteLine statements in the previous example.

dyn = dyn + 3;
obj = obj + 3;

Un error del compilador se notifica para el intento de suma de un entero y un objeto en la expresión obj + 3.A compiler error is reported for the attempted addition of an integer and an object in expression obj + 3. En cambio, no se notifica ningún error para dyn + 3.However, no error is reported for dyn + 3. En tiempo de compilación no se comprueba la expresión que contiene dyn porque el tipo de dyn es dynamic.The expression that contains dyn is not checked at compile time because the type of dyn is dynamic.

El ejemplo siguiente usa dynamic en varias declaraciones.The following example uses dynamic in several declarations. El método Main también contrasta la comprobación de tipo en tiempo de compilación con la comprobación de tipo en tiempo de ejecución.The Main method also contrasts compile-time type checking with run-time type checking.

using System;

namespace DynamicExamples
{
    class Program
    {
        static void Main(string[] args)
        {
            ExampleClass ec = new ExampleClass();
            Console.WriteLine(ec.exampleMethod(10));
            Console.WriteLine(ec.exampleMethod("value"));

            // The following line causes a compiler error because exampleMethod
            // takes only one argument.
            //Console.WriteLine(ec.exampleMethod(10, 4));

            dynamic dynamic_ec = new ExampleClass();
            Console.WriteLine(dynamic_ec.exampleMethod(10));

            // Because dynamic_ec is dynamic, the following call to exampleMethod
            // with two arguments does not produce an error at compile time.
            // However, it does cause a run-time error. 
            //Console.WriteLine(dynamic_ec.exampleMethod(10, 4));
        }
    }

    class ExampleClass
    {
        static dynamic field;
        dynamic prop { get; set; }

        public dynamic exampleMethod(dynamic d)
        {
            dynamic local = "Local variable";
            int two = 2;

            if (d is int)
            {
                return local;
            }
            else
            {
                return two;
            }
        }
    }
}
// Results:
// Local variable
// 2
// Local variable

Vea tambiénSee also