Tipos de referência internos (Referência de C#)Built-in reference types (C# reference)

O C# tem um número de tipos de referência internos.C# has a number of built-in reference types. Eles têm palavras-chave ou operadores que são sinônimos de um tipo na biblioteca do .NET.They have keywords or operators that are synonyms for a type in the .NET library.

O tipo de objetoThe object type

O tipo object é um alias de System.Object no .NET.The object type is an alias for System.Object in .NET. No sistema de tipos unificado do C#, todos os tipos, predefinidos e definidos pelo usuário, tipos de referência e tipos de valor, herdam direta ou indiretamente 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. Você pode atribuir valores de qualquer tipo a variáveis do tipo object.You can assign values of any type to variables of type object. Qualquer variável object pode ser atribuída ao seu valor padrão usando o literal null.Any object variable can be assigned to its default value using the literal null. Quando uma variável de um tipo de valor é convertida para um objeto, ela é chamada de boxed.When a variable of a value type is converted to object, it is said to be boxed. Quando uma variável object de tipo é convertida em um tipo de valor, diz-se que ela não está encaixotada.When a variable of type object is converted to a value type, it is said to be unboxed. Para obter mais informações, consulte Conversões boxing e unboxing.For more information, see Boxing and Unboxing.

O tipo de cadeia de caracteresThe string type

O tipo string representa uma sequência de zero ou mais caracteres Unicode.The string type represents a sequence of zero or more Unicode characters. string é um alias de System.String no .NET.string is an alias for System.String in .NET.

Embora string seja um tipo de referência, os operadores de igualdade == e != são definidos para comparar os valores de objetos string, não referências.Although string is a reference type, the equality operators == and != are defined to compare the values of string objects, not references. Isso torna o teste de igualdade de cadeia de caracteres mais intuitivo.This makes testing for string equality more intuitive. Por exemplo: 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));

Isso exibe "True" e, em seguida, "False" porque os conteúdos das cadeias de caracteres são equivalentes, mas a e b não fazem referência à mesma instância da cadeia de caracteres.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.

O operador + concatena as cadeias de caracteres:The + operator concatenates strings:

string a = "good " + "morning";

Isso cria um objeto de cadeia de caracteres que contém “good morning”.This creates a string object that contains "good morning".

Cadeias de caracteres são imutável – o conteúdo de um objeto de cadeia de caracteres não pode ser alterado depois que o objeto é criado, embora a sintaxe faça com que pareça que você pode fazer isso.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 exemplo, quando você escreve esse código, o compilador, na verdade, cria um objeto de cadeia de caracteres para manter a nova sequência de caracteres e esse novo objeto é atribuído 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. A memória que tiver sido alocada para b (quando ela continha a cadeia de caracteres "h") será elegível para a coleta de lixo.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";

O [] operador pode ser usado para ler apenas acesso a caracteres individuais de uma string.The [] operator can be used for readonly access to individual characters of a string. Os valores 0 de índice válidos começam e devem ser menores do que o comprimento da seqüência:Valid index values start at 0 and must be less than the length of the string:

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

Da mesma forma, o [] operador também pode ser usado para iterar sobre cada caractere em uma seqüência: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

Literais de cadeia de caracteres são do tipo string e podem ser escritos de duas formas, entre aspas e @.String literals are of type string and can be written in two forms, quoted and @-quoted. Os literais de cadeia de caracteres entre aspas são colocados entre aspas duplas ("):Quoted string literals are enclosed in double quotation marks ("):

"good morning"  // a string literal

Os literais de cadeia de caracteres podem conter qualquer literal de caractere.String literals can contain any character literal. Sequências de escape são incluídas.Escape sequences are included. O exemplo a seguir usa a sequência de escape \\ de barra invertida, \u0066 para a letra f e \n para a nova linha.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

Observação

O código de escape \udddd (em que dddd é um número de quatro dígitos) representa o caractere Unicode U+dddd.The escape code \udddd (where dddd is a four-digit number) represents the Unicode character U+dddd. Os códigos de escape Unicode de oito dígitos também são reconhecidos: \Udddddddd.Eight-digit Unicode escape codes are also recognized: \Udddddddd.

Os literais de cadeia de caracteres textuais começam com @ e também são colocados entre aspas duplas.Verbatim string literals start with @ and are also enclosed in double quotation marks. Por exemplo: For example:

@"good morning"  // a string literal

A vantagem das cadeias de caracteres textuais é que as sequências de escape não são processadas, o que torna mais fácil escrever, por exemplo, um nome de arquivo totalmente qualificado do Windows: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 aspas duplas em uma cadeia de caracteres @-quoted, dobre-a:To include a double quotation mark in an @-quoted string, double it:

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

O tipo de delegadoThe delegate type

A declaração de um tipo de delegado é semelhante a uma assinatura de método.The declaration of a delegate type is similar to a method signature. Ela tem um valor retornado e parâmetros de qualquer 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);

No .NET, os tipos System.Action e System.Func fornecem definições genéricas para muitos delegados comuns.In .NET, System.Action and System.Func types provide generic definitions for many common delegates. Você provavelmente não precisa definir novos tipos de delegado personalizado.You likely don't need to define new custom delegate types. Em vez disso, é possível criar instâncias dos tipos genéricos fornecidos.Instead, you can create instantiations of the provided generic types.

Um delegate é um tipo de referência que pode ser usado para encapsular um método nomeado ou anônimo.A delegate is a reference type that can be used to encapsulate a named or an anonymous method. Representantes são semelhantes a ponteiros de função em C++. No entanto, os representantes são fortemente tipados e seguros.Delegates are similar to function pointers in C++; however, delegates are type-safe and secure. Para aplicativos de representantes, consulte Representantes e Representantes genéricos.For applications of delegates, see Delegates and Generic Delegates. Os representantes são a base dos Eventos.Delegates are the basis for Events. Um delegado pode ser instanciado associando-o a um método nomeado ou anônimo.A delegate can be instantiated by associating it either with a named or anonymous method.

O delegado deve ser instanciado com um método ou expressão lambda que tenha um tipo de retorno compatível e parâmetros de entrada.The delegate must be instantiated with a method or lambda expression that has a compatible return type and input parameters. Para obter mais informações sobre o grau de variação permitido na assinatura do método, consulte Variação em representantes.For more information on the degree of variance that is allowed in the method signature, see Variance in Delegates. Para uso com métodos anônimos, o delegado e o código a ser associado a ele são declarados juntos.For use with anonymous methods, the delegate and the code to be associated with it are declared together.

O tipo dinâmicoThe dynamic type

O tipo dynamic indica que o uso de variável e as referências aos seus membros ignoram a verificação de tipo de tempo de compilação.The dynamic type indicates that use of the variable and references to its members bypass compile-time type checking. Em vez disso, essas operações são resolvidas em tempo de execução.Instead, these operations are resolved at run time. O tipo dynamic simplifica o acesso a APIs COM, como as APIs de Automação do Office e também às APIs dinâmicas, como bibliotecas do IronPython e ao DOM (Modelo de Objeto do Documento) 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).

O tipo dynamic se comporta como o tipo object na maioria das circunstâncias.Type dynamic behaves like type object in most circumstances. Em particular, qualquer expressão não nula pode ser convertida no tipo dynamic.In particular, any non-null expression can be converted to the dynamic type. O tipo dynamic é diferente de object nas operações que contêm expressões do tipo dynamic não resolvidas ou com tipo verificado pelo compilador.The dynamic type differs from object in that operations that contain expressions of type dynamic are not resolved or type checked by the compiler. O compilador junta as informações sobre a operação em pacotes e, posteriormente, essas informações são usadas para avaliar a operação em tempo de execução.The compiler packages together information about the operation, and that information is later used to evaluate the operation at run time. Como parte do processo, as variáveis do tipo dynamic são compiladas em variáveis do tipo object.As part of the process, variables of type dynamic are compiled into variables of type object. Portanto, o tipo dynamic existe somente em tempo de compilação e não em tempo de execução.Therefore, type dynamic exists only at compile time, not at run time.

O exemplo a seguir compara uma variável do tipo dynamic a uma variável do tipo object.The following example contrasts a variable of type dynamic to a variable of type object. Para verificar o tipo de cada variável no tempo de compilação, coloque o ponteiro do mouse sobre dyn ou obj nas instruções WriteLine.To verify the type of each variable at compile time, place the mouse pointer over dyn or obj in the WriteLine statements. Copie o seguinte código para um editor em que o IntelliSense está disponível.Copy the following code into an editor where IntelliSense is available. O IntelliSense mostra dinâmico para dyn e objeto 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());
    }
}

As instruções WriteLine exibem os tipos de tempo de execução de dyn e obj.The WriteLine statements display the run-time types of dyn and obj. Nesse ponto, ambos têm o mesmo tipo, inteiro.At that point, both have the same type, integer. A saída a seguir será produzida:The following output is produced:

System.Int32
System.Int32

Para ver a diferença entre dyn e obj em tempo de compilação, adicione as duas linhas a seguir entre as declarações e as instruções WriteLine no exemplo 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;

Um erro de compilador será relatado em virtude da tentativa de adição de um inteiro e um objeto à expressão obj + 3.A compiler error is reported for the attempted addition of an integer and an object in expression obj + 3. No entanto, nenhum erro será relatado para dyn + 3.However, no error is reported for dyn + 3. A expressão contém dyn não é verificada em tempo de compilação, pois o tipo de dyn é dynamic.The expression that contains dyn is not checked at compile time because the type of dyn is dynamic.

O exemplo a seguir usa dynamic em várias declarações.The following example uses dynamic in several declarations. O método Main também compara a verificação de tipo em tempo de compilação com a verificação de tipo em tempo de execução.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

Confira tambémSee also