Tipos (Guia de Programação em C#)Types (C# Programming Guide)

Tipos, variáveis e valoresTypes, Variables, and Values

C# é uma linguagem fortemente tipada.C# is a strongly-typed language. Todas as variáveis e constantes têm um tipo, assim como cada expressão que é avaliada como um valor.Every variable and constant has a type, as does every expression that evaluates to a value. Cada assinatura de método especifica um tipo para cada parâmetro de entrada e para o valor retornado.Every method signature specifies a type for each input parameter and for the return value. A biblioteca de classes do .NET define um conjunto de tipos numéricos internos, bem como tipos mais complexos que representam uma ampla variedade de constructos lógicos, como o sistema de arquivos, as conexões de rede, as coleções e as matrizes de objetos e as datas.The .NET class library defines a set of built-in numeric types as well as more complex types that represent a wide variety of logical constructs, such as the file system, network connections, collections and arrays of objects, and dates. Um programa em C# típico usa tipos da biblioteca de classes, bem como tipos definidos pelo usuário que modelam os conceitos que são específicos para o domínio do problema do programa.A typical C# program uses types from the class library as well as user-defined types that model the concepts that are specific to the program's problem domain.

As informações armazenadas em um tipo podem incluir o seguinte:The information stored in a type can include the following:

  • O espaço de armazenamento que uma variável do tipo requer.The storage space that a variable of the type requires.

  • Os valores mínimo e máximo que ele pode representar.The maximum and minimum values that it can represent.

  • Os membros (métodos, campos, eventos e etc.) que ele contém.The members (methods, fields, events, and so on) that it contains.

  • O tipo base do qual ele herda.The base type it inherits from.

  • O local no qual a memória para as variáveis será alocada em tempo de execução.The location where the memory for variables will be allocated at run time.

  • Os tipos de operações que são permitidos.The kinds of operations that are permitted.

O compilador usa as informações de tipo para garantir que todas as operações que são realizadas em seu código sejam fortemente tipadas.The compiler uses type information to make sure that all operations that are performed in your code are type safe. Por exemplo, se você declarar uma variável do tipo int, o compilador permitirá que você use a variável nas operações de adição e subtração.For example, if you declare a variable of type int, the compiler allows you to use the variable in addition and subtraction operations. Se você tentar executar as mesmas operações em uma variável do tipo bool, o compilador gerará um erro, como mostrado no exemplo a seguir:If you try to perform those same operations on a variable of type bool, the compiler generates an error, as shown in the following example:

int a = 5;             
int b = a + 2; //OK

bool test = true;
  
// Error. Operator '+' cannot be applied to operands of type 'int' and 'bool'.
int c = a + test;

Observação

Desenvolvedores de C e C++, observem que, em C#, bool não é conversível em int.C and C++ developers, notice that in C#, bool is not convertible to int.

O compilador insere as informações de tipo no arquivo executável como metadados.The compiler embeds the type information into the executable file as metadata. O CLR (Common Language Runtime) usa metadados em tempo de execução para garantir mais segurança de tipos quando aloca e recupera a memória.The common language runtime (CLR) uses that metadata at run time to further guarantee type safety when it allocates and reclaims memory.

Especificando tipos em declarações de variávelSpecifying Types in Variable Declarations

Quando declara uma variável ou constante em um programa, você deve especificar seu tipo ou usar a palavra-chave var para permitir que o compilador infira o tipo.When you declare a variable or constant in a program, you must either specify its type or use the var keyword to let the compiler infer the type. O exemplo a seguir mostra algumas declarações de variáveis que usam tipos numéricos internos e tipos complexos definidos pelo usuário:The following example shows some variable declarations that use both built-in numeric types and complex user-defined types:

// Declaration only:
float temperature;
string name;
MyClass myClass;

// Declaration with initializers (four examples):
char firstLetter = 'C';
var limit = 3;
int[] source = { 0, 1, 2, 3, 4, 5 };
var query = from item in source
            where item <= limit
            select item;

Os tipos de parâmetros de método e valores de retorno são especificados na assinatura do método.The types of method parameters and return values are specified in the method signature. A assinatura a seguir mostra um método que requer um int como um argumento de entrada e retorna uma cadeia de caracteres:The following signature shows a method that requires an int as an input argument and returns a string:

public string GetName(int ID)
{
    if (ID < names.Length)
        return names[ID];
    else
        return String.Empty;
}
private string[] names = { "Spencer", "Sally", "Doug" };

Depois que uma variável é declarada, ela não pode ser declarada novamente com um novo tipo e não pode ter um valor atribuído que não seja compatível com seu tipo declarado.After a variable is declared, it cannot be re-declared with a new type, and it cannot be assigned a value that is not compatible with its declared type. Por exemplo, você não pode declarar um int e, em seguida, atribuir a ele um valor booliano de true.For example, you cannot declare an int and then assign it a Boolean value of true. No entanto, os valores podem ser convertidos em outros tipos, por exemplo, quando são passados como argumentos de método ou atribuídos a novas variáveis.However, values can be converted to other types, for example when they are assigned to new variables or passed as method arguments. Uma conversão de tipo que não causa a perda de dados é executada automaticamente pelo compilador.A type conversion that does not cause data loss is performed automatically by the compiler. Uma conversão que pode causar perda de dados requer um cast no código-fonte.A conversion that might cause data loss requires a cast in the source code.

Para obter mais informações, consulte Conversões e conversões de Tipo.For more information, see Casting and Type Conversions.

Tipos internosBuilt-in Types

O C# fornece um conjunto padrão de tipos numéricos internos para representar números inteiros, valores de ponto flutuante, expressões boolianas, caracteres de texto, valores decimais e outros tipos de dados.C# provides a standard set of built-in numeric types to represent integers, floating point values, Boolean expressions, text characters, decimal values, and other types of data. Também há tipos string e object internos.There are also built-in string and object types. Eles estão disponíveis para uso em qualquer programa em C#.These are available for you to use in any C# program. Para obter mais informações sobre os tipos internos, consulte Tabelas de referência de tipos.For more information about the built-in types, see Reference Tables for Types.

Tipos personalizadosCustom Types

Você usa os constructos struct, classe, interface e enum para criar seus próprios tipos personalizados.You use the struct, class, interface, and enum constructs to create your own custom types. A biblioteca de classes do .NET em si é uma coleção de tipos personalizados fornecida pela Microsoft, que você pode usar em seus próprios aplicativos.The .NET class library itself is a collection of custom types provided by Microsoft that you can use in your own applications. Por padrão, os tipos usados com mais frequência na biblioteca de classes estão disponíveis em qualquer programa em C#.By default, the most frequently used types in the class library are available in any C# program. Outros ficam disponíveis somente quando você adiciona explicitamente uma referência de projeto ao assembly no qual eles estão definidos.Others become available only when you explicitly add a project reference to the assembly in which they are defined. Após o compilador ter uma referência ao assembly, você pode declarar variáveis (e constantes) dos tipos declarados no assembly no código-fonte.After the compiler has a reference to the assembly, you can declare variables (and constants) of the types declared in that assembly in source code. Para saber mais, confira Biblioteca de classes do .NET.For more information, see .NET Class Library.

O CTS (Common Type System)The Common Type System

É importante entender os dois pontos fundamentais sobre o sistema de tipos do .NET:It is important to understand two fundamental points about the type system in .NET:

  • Ele dá suporte ao conceito de herança.It supports the principle of inheritance. Os tipos podem derivar de outros tipos, chamados tipos base.Types can derive from other types, called base types. O tipo derivado herda (com algumas restrições) os métodos, as propriedades e outros membros do tipo base.The derived type inherits (with some restrictions) the methods, properties, and other members of the base type. O tipo base, por sua vez, pode derivar de algum outro tipo, nesse caso, o tipo derivado herda os membros de ambos os tipos base na sua hierarquia de herança.The base type can in turn derive from some other type, in which case the derived type inherits the members of both base types in its inheritance hierarchy. Todos os tipos, incluindo tipos numéricos internos, como System.Int32 (palavra-chave de C#: int), derivam, em última análise, de um único tipo base, que é o System.Object (palavra-chave de C#: object).All types, including built-in numeric types such as System.Int32 (C# keyword: int), derive ultimately from a single base type, which is System.Object (C# keyword: object). Essa hierarquia unificada de tipos é chamada de CTS (Common Type System).This unified type hierarchy is called the Common Type System (CTS). Para obter mais informações sobre herança em C#, consulte Herança.For more information about inheritance in C#, see Inheritance.

  • Cada tipo no CTS é definido como um tipo de valor ou um tipo de referência.Each type in the CTS is defined as either a value type or a reference type. Isso inclui todos os tipos personalizados na biblioteca de classes do .NET, além de tipos personalizados definidos pelo usuário.This includes all custom types in the .NET class library and also your own user-defined types. Os tipos que você define usando a palavra-chave struct são tipos de valor. Todos os tipos numéricos internos são structs.Types that you define by using the struct keyword are value types; all the built-in numeric types are structs. Os tipos que você define usando a palavra-chave classe são tipos de referência.Types that you define by using the class keyword are reference types. Os tipos de referência e os tipos de valor têm diferentes regras de tempo de compilação e comportamento de tempo de execução diferente.Reference types and value types have different compile-time rules, and different run-time behavior.

A ilustração a seguir mostra a relação entre tipos de referência e tipos de valor no CTS.The following illustration shows the relationship between value types and reference types in the CTS.

Tipos de valor e tipos de referênciaValue Types and Reference Types
Tipos de Valor e tipos de referência no CTSValue types and reference types in the CTS

Observação

Você pode ver que os tipos mais usados normalmente são todos organizados no namespace System.You can see that the most commonly used types are all organized in the System namespace. No entanto, o namespace no qual um tipo está contido não tem relação com a possibilidade de ele ser um tipo de valor ou um tipo de referência.However, the namespace in which a type is contained has no relation to whether it is a value type or reference type.

Tipos de valorValue Types

Os tipos de valor derivam de System.ValueType, que deriva de System.Object.Value types derive from System.ValueType, which derives from System.Object. Os tipos que derivam de System.ValueType apresentam um comportamento especial no CLR.Types that derive from System.ValueType have special behavior in the CLR. As variáveis de tipo de valor contêm diretamente seus valores, o que significa que a memória é alocada embutida em qualquer contexto em que a variável é declarada.Value type variables directly contain their values, which means that the memory is allocated inline in whatever context the variable is declared. Não há nenhuma alocação de heap separada ou sobrecarga de coleta de lixo para variáveis do tipo de valor.There is no separate heap allocation or garbage collection overhead for value-type variables.

Há duas categorias de tipos de valor: struct e enum.There are two categories of value types: struct and enum.

Os tipos numéricos internos são structs e têm propriedades e métodos que você pode acessar:The built-in numeric types are structs, and they have properties and methods that you can access:

// Static method on type Byte.  
byte b = Byte.MaxValue;  

Mas você declara e atribui valores a eles como se fossem tipos de não agregação simples:But you declare and assign values to them as if they were simple non-aggregate types:

byte num = 0xA;  
int i = 5;  
char c = 'Z';  

Tipos de valor são lacrados, o que significa, por exemplo, que você não pode derivar um tipo de System.Int32 e não pode definir um struct para herdar de qualquer struct ou classe definida pelo usuário, porque um struct apenas pode herdar de System.ValueType.Value types are sealed, which means, for example, that you cannot derive a type from System.Int32, and you cannot define a struct to inherit from any user-defined class or struct because a struct can only inherit from System.ValueType. No entanto, um struct pode implementar uma ou mais interfaces.However, a struct can implement one or more interfaces. Você pode converter um tipo de struct em um tipo de interface. Isso faz com que uma operação de conversão boxing encapsule o struct dentro de um objeto de tipo de referência no heap gerenciado.You can cast a struct type to an interface type; this causes a boxing operation to wrap the struct inside a reference type object on the managed heap. As operações de conversão boxing ocorrem quando você passa um tipo de valor para um método que usa um System.Object como parâmetro de entrada.Boxing operations occur when you pass a value type to a method that takes a System.Object as an input parameter. Para obter mais informações, consulte Boxing e unboxing.For more information, see Boxing and Unboxing.

Você usa a palavra-chave struct para criar seus próprios tipos de valor personalizados.You use the struct keyword to create your own custom value types. Normalmente, um struct é usado como um contêiner para um pequeno conjunto de variáveis relacionadas, conforme mostrado no exemplo a seguir:Typically, a struct is used as a container for a small set of related variables, as shown in the following example:

public struct CoOrds
{
    public int x, y;

    public CoOrds(int p1, int p2)
    {
        x = p1;
        y = p2;
    }
}

Para obter mais informações sobre structs, consulte Structs.For more information about structs, see Structs. Para saber mais sobre os tipos de valor do .NET, confira Tipos de valor.For more information about value types in .NET, see Value Types.

A outra categoria de tipos de valor é enum.The other category of value types is enum. Uma enum define um conjunto de constantes integrais nomeadas.An enum defines a set of named integral constants. Por exemplo, a enumeração System.IO.FileMode na biblioteca de classes do .NET contém um conjunto de números inteiros constantes nomeados que especificam como um arquivo deve ser aberto.For example, the System.IO.FileMode enumeration in the .NET class library contains a set of named constant integers that specify how a file should be opened. Ela é definida conforme mostrado no exemplo abaixo:It is defined as shown in the following example:

public enum FileMode
{
    CreateNew = 1,
    Create = 2,
    Open = 3,
    OpenOrCreate = 4,
    Truncate = 5,
    Append = 6,
}

A constante System.IO.FileMode.Create tem um valor de 2.The System.IO.FileMode.Create constant has a value of 2. No entanto, o nome é muito mais significativo para a leitura do código-fonte por humanos e, por esse motivo, é melhor usar enumerações em vez de números literais constantes.However, the name is much more meaningful for humans reading the source code, and for that reason it is better to use enumerations instead of constant literal numbers. Para obter mais informações, consulte System.IO.FileMode.For more information, see System.IO.FileMode.

Todas as enumerações herdam de System.Enum, que herda de System.ValueType.All enums inherit from System.Enum, which inherits from System.ValueType. Todas as regras que se aplicam a structs também se aplicam a enums.All the rules that apply to structs also apply to enums. Para obter mais informações sobre enums, consulte Tipos de enumeração.For more information about enums, see Enumeration Types.

Tipos de referênciaReference Types

Um tipo que é definido como uma classe, delegado, matriz ou interface é um tipo de referência.A type that is defined as a class, delegate, array, or interface is a reference type. No tempo de execução, quando você declara uma variável de um tipo de referência, a variável contém o valor null até você criar explicitamente um objeto usando o operador new ou atribuir a ele um objeto que foi criado em outro lugar com o operador new, conforme mostrado no exemplo a seguir:At run time, when you declare a variable of a reference type, the variable contains the value null until you explicitly create an object by using the new operator, or assign it an object that has been created elsewhere by using new, as shown in the following example:

MyClass mc = new MyClass();  
MyClass mc2 = mc;  

Uma interface deve ser inicializada com um objeto da classe que a implementa.An interface must be initialized together with a class object that implements it. Se MyClass implementa IMyInterface, você cria uma instância de IMyInterface, conforme mostrado no exemplo a seguir:If MyClass implements IMyInterface, you create an instance of IMyInterface as shown in the following example:

IMyInterface iface = new MyClass();  

Quando o objeto é criado, a memória é alocada no heap gerenciado e a variável contém apenas uma referência para o local do objeto.When the object is created, the memory is allocated on the managed heap, and the variable holds only a reference to the location of the object. Os tipos no heap gerenciado requerem sobrecarga quando são alocados e quando são recuperados pela funcionalidade de gerenciamento automático de memória do CLR, que é conhecida como coleta de lixo.Types on the managed heap require overhead both when they are allocated and when they are reclaimed by the automatic memory management functionality of the CLR, which is known as garbage collection. No entanto, a coleta de lixo também é altamente otimizada e na maioria dos cenários não cria um problema de desempenho.However, garbage collection is also highly optimized, and in most scenarios it does not create a performance issue. Para obter mais informações sobre a coleta de lixo, consulte Gerenciamento automático de memória.For more information about garbage collection, see Automatic Memory Management.

Todas as matrizes são tipos de referência, mesmo se seus elementos forem tipos de valor.All arrays are reference types, even if their elements are value types. As matrizes derivam implicitamente da classe System.Array, mas você declara e usa as matrizes com a sintaxe simplificada fornecida pelo C#, conforme mostrado no exemplo a seguir:Arrays implicitly derive from the System.Array class, but you declare and use them with the simplified syntax that is provided by C#, as shown in the following example:

// Declare and initialize an array of integers.
int[] nums = { 1, 2, 3, 4, 5 };

// Access an instance property of System.Array.
int len = nums.Length;

Os tipos de referência dão suporte completo à herança.Reference types fully support inheritance. Ao criar uma classe, você pode herdar de outra interface ou classe que não está definida como lacrada, e outras classes podem herdar de sua classe e substituir os métodos virtuais.When you create a class, you can inherit from any other interface or class that is not defined as sealed, and other classes can inherit from your class and override your virtual methods. Para obter mais informações sobre como criar suas próprias classes, consulte Classes e structs.For more information about how to create your own classes, see Classes and Structs. Para obter mais informações sobre herança e métodos virtuais, consulte Herança.For more information about inheritance and virtual methods, see Inheritance.

Tipos de valores literaisTypes of Literal Values

No C#, valores literais recebem um tipo do compilador.In C#, literal values receive a type from the compiler. Você pode especificar como um literal numérico deve ser digitado anexando uma letra ao final do número.You can specify how a numeric literal should be typed by appending a letter to the end of the number. Por exemplo, para especificar que o valor 4,56 deve ser tratado como um float, acrescente um "f" ou "F" após o número: 4.56f.For example, to specify that the value 4.56 should be treated as a float, append an "f" or "F" after the number: 4.56f. Se nenhuma letra for anexada, o compilador inferirá um tipo para o literal.If no letter is appended, the compiler will infer a type for the literal. Para obter mais informações sobre quais tipos podem ser especificados com sufixos de letra, consulte as páginas de referência de tipos individuais em Tipos de valor.For more information about which types can be specified with letter suffixes, see the reference pages for individual types in Value Types.

Como os literais são tipados e todos os tipos derivam basicamente de System.Object, você pode escrever e compilar o código como o seguinte:Because literals are typed, and all types derive ultimately from System.Object, you can write and compile code such as the following:

string s = "The answer is " + 5.ToString();
// Outputs: "The answer is 5"
Console.WriteLine(s);

Type type = 12345.GetType();
// Outputs: "System.Int32"
Console.WriteLine(type);

Tipos genéricosGeneric Types

Um tipo pode ser declarado com um ou mais parâmetros de tipo que servem como um espaço reservado para o tipo real (o tipo concreto) que o código do cliente fornecerá ao criar uma instância do tipo.A type can be declared with one or more type parameters that serve as a placeholder for the actual type (the concrete type) that client code will provide when it creates an instance of the type. Esses tipos são chamados de tipos genéricos.Such types are called generic types. Por exemplo, o tipo do .NET System.Collections.Generic.List<T> tem um parâmetro de tipo que, por convenção, recebe o nome T. Ao criar uma instância do tipo, você pode especificar o tipo dos objetos que a lista conterá, por exemplo, a cadeia de caracteres:For example, the .NET type System.Collections.Generic.List<T> has one type parameter that by convention is given the name T. When you create an instance of the type, you specify the type of the objects that the list will contain, for example, string:

List<string> stringList = new List<string>();
stringList.Add("String example");
// compile time error adding a type other than a string:
stringList.Add(4);

O uso do parâmetro de tipo possibilita a reutilização da mesma classe para conter qualquer tipo de elemento sem precisar converter cada elemento em objeto.The use of the type parameter makes it possible to reuse the same class to hold any type of element, without having to convert each element to object. As classes de coleção genéricas são chamadas de coleções fortemente tipadas porque o compilador sabe o tipo específico dos elementos da coleção e pode gerar um erro em tempo de compilação se, por exemplo, você tentar adicionar um inteiro ao objeto stringList no exemplo anterior.Generic collection classes are called strongly-typed collections because the compiler knows the specific type of the collection's elements and can raise an error at compile-time if, for example, you try to add an integer to the stringList object in the previous example. Para obter mais informações, consulte Genéricos.For more information, see Generics.

Tipos implícitos, tipos anônimos e tipos que permitem valor nuloImplicit Types, Anonymous Types, and Nullable Types

Conforme mencionado anteriormente, você pode digitar implicitamente uma variável local (mas não os membros de classe) usando a palavra-chave var.As stated previously, you can implicitly type a local variable (but not class members) by using the var keyword. A variável ainda recebe um tipo em tempo de compilação, mas o tipo é fornecido pelo compilador.The variable still receives a type at compile time, but the type is provided by the compiler. Para obter mais informações, consulte Variáveis locais de tipo implícito.For more information, see Implicitly Typed Local Variables.

Em alguns casos, é inconveniente criar um tipo nomeado para conjuntos simples de valores relacionados que você não pretende armazenar ou transmitir fora dos limites de método.In some cases, it is inconvenient to create a named type for simple sets of related values that you do not intend to store or pass outside method boundaries. Você pode criar tipos anônimos para essa finalidade.You can create anonymous types for this purpose. Para obter mais informações, consulte Tipos anônimos.For more information, see Anonymous Types.

Os tipos comuns de valor não podem ter um valor nulo.Ordinary value types cannot have a value of null. No entanto, você pode criar tipos de valor anulável afixando uma ? após o tipo.However, you can create nullable value types by affixing a ? after the type. Por exemplo, int? é um tipo int que também pode ter o valor nulo.For example, int? is an int type that can also have the value null. No CTS, os tipos anuláveis são instâncias do tipo struct genérico System.Nullable<T>.In the CTS, nullable types are instances of the generic struct type System.Nullable<T>. Os tipos que permitem valor nulo são especialmente úteis quando você está passando dados entre bancos de dados nos quais os valores numéricos podem ser nulos.Nullable types are especially useful when you are passing data to and from databases in which numeric values might be null. Para obter mais informações, consulte Tipos que permitem valor nulo.For more information, see Nullable Types.

Para mais informações, consulte os seguintes tópicos:For more information, see the following topics:

Especificação da Linguagem C#C# Language Specification

Para obter mais informações, consulte a Especificação da linguagem C#.For more information, see the C# Language Specification. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso de C#.The language specification is the definitive source for C# syntax and usage.

Consulte tambémSee Also

Referência de C#C# Reference
Guia de Programação em C#C# Programming Guide
Conversão de tipos de dados XMLConversion of XML Data Types
Tabela de tipos integraisIntegral Types Table