Tipos (guia de programação do C#)
Tipos, variáveis e valores
C# é uma linguagem fortemente tipada.Cada variável e constante tem um tipo, como cada expressão que avalia um valor.Cada assinatura do método Especifica um tipo para cada parâmetro de entrada e para o valor de retorno.A.NET Framework class library define um conjunto de tipos numéricos internos, como também os tipos mais complexos que representam uma grande variedade de construções lógicas, como o sistema de arquivos, conexões de rede, coleções e matrizes de objetos e as datas.Um programa 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.
As informações armazenadas em um tipo podem incluir o seguinte:
O espaço de armazenamento que necessita de uma variável do tipo.
Os valores máximo e mínimos que ele possa representar.
Os membros (métodos, campos, eventos e assim por diante) que ele contém.
O tipo base que ela herda.
O local de memória onde as variáveis serão alocadas em tempo de execução.
Os tipos de operações que são permitidos.
O compilador usa as informações de tipo para certificar-se de que todas as operações são executadas em seu código são segurança de tipos.Por exemplo, se você declarar uma variável do tipo int, o compilador permite que você use a variável além e operações de subtração.Se você tenta executar as mesmas operações em uma variável do tipo bool, o compilador gera um erro, como mostrado no exemplo a seguir:
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 |
---|
Os desenvolvedores de c e C++, observe que, em C#, bool não pode ser convertido para int. |
O compilador incorpora as informações de tipo no arquivo executável como metadados.O common language runtime (CLR) usa esses metadados em tempo de execução para garantir mais segurança de tipo quando ele aloca e recupera da memória.
Especificando tipos nas declarações de variável
Quando você declara uma variável ou constante em um programa, você deve especificar o tipo ou use o var palavra-chave para permitir que o compilador a inferir o tipo.O exemplo a seguir mostra algumas declarações de variáveis que usam tipos numéricos internos e tipos definidos pelo usuário:
// 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 do método e valores de retorno são especificados na assinatura do método.A assinatura a seguir mostra um método que requer um int como um argumento de entrada e retorna uma seqüência de caracteres:
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 for declarada, ela não pode ser redeclarada com um novo tipo e ela não pode ser atribuída a um valor que não é compatível com seu tipo declarado.Por exemplo, você não pode declarar um int e, em seguida, atribua a ela um valor booleano de true.No entanto, valores podem ser convertidos a outros tipos, por exemplo quando eles são atribuídos a variáveis novas ou passados como argumentos de método.A conversão de tipo que faz a perda de dados de causa não é executada automaticamente pelo compilador.Uma conversão que pode causar a perda de dados requer um cast o código-fonte.
Para obter mais informações, consulte Elenco e conversões de tipo (guia de programação do C#).
Tipos internos
C# fornece um conjunto padrão de tipos numéricos internos para representar números inteiros, flutuante, valores de ponto, expressões booleanas, caracteres de texto, valores decimais e outros tipos de dados.Também há interno string e object tipos.Eles estão disponíveis para uso em qualquer programa C#.Para obter mais informações sobre os tipos internos, consulte Tabelas de referência para tipos (Referência C#).
Tipos personalizados
Você pode usar o struct, classe, interface, e enum construções para criar seus próprios tipos personalizados.A.NET Framework propriamente dito é uma coleção de tipos personalizados fornecidos pela Microsoft que você pode usar em seus próprios aplicativos.Por padrão, os tipos mais freqüentemente usados na biblioteca de classes estão disponíveis em qualquer programa C#.Outras ficam disponíveis somente quando você adiciona uma referência ao assembly no qual eles são definidos explicitamente.Depois que o compilador não tem uma referência ao assembly, você pode declarar variáveis (e constantes) dos tipos declarados no assembly no código-fonte.Para obter mais informações, consulte .NET Framework Class Library.
Common Type System
É importante compreender dois pontos fundamentais sobre o sistema de tipos na .NET Framework:
Ele suporta o princípio de herança.Tipos podem derivar de outros tipos, chamados tipos base.O tipo derivado herda (com algumas restrições), os métodos, propriedades e outros membros do tipo base.Por sua vez, o tipo base pode derivar de algum outro tipo, no qual o caso o tipo derivado herda os membros de ambos os tipos base em sua hierarquia de herança.Todos os tipos, incluindo tipos numéricos internos, como System.Int32 (palavra-chave C#: int), derivam, por fim, a partir de um único tipo de base, que é System.Object (palavra-chave C#: objeto).Essa hierarquia unificado de tipos é chamada a Common Type System (CTS).Para obter mais informações sobre herança em C#, consulte Herança (guia de programação do C#).
Cada tipo do CTS é definido como um tipo de valor ou um tipo de referência.Isso inclui todos os tipos personalizados na.NET Framework e também seus próprios tipos definidos pelo usuário.Os tipos definidos usando o struct palavra-chave são tipos de valor; todos os tipos numéricos internos são structs.Os tipos definidos usando o classe palavra-chave são referência tipos.Tipos de referência e valor têm regras diferentes do tempo de compilação e comportamento diferente do tempo de execução.
A ilustração a seguir mostra a relação entre tipos de valor e tipos de referência no CTS.
Tipos de valor e a referência a tipos no CTS
Observação |
---|
Você pode ver que os tipos mais comumente usados são todos organizados da System espaço para nome.No entanto, o namespace em que um tipo está contido não tem nenhuma relação se ele é um valor de tipo ou tipo de referência. |
Tipos de valor
Derivam de tipos de valor de System.ValueType, que é derivada de System.Object.Tipos que derivam da System.ValueType têm um comportamento especial no CLR.As variáveis do tipo de valor contêm diretamente seus valores, que significa que a memória é alocada inline em qualquer contexto em que a variável é declarada.Não há nenhuma alocação de heap separada ou uma sobrecarga de coleta de lixo para variáveis do tipo de valor.
Há duas categorias de tipos de valor: struct e enum.
Os tipos numéricos internos são structs e têm propriedades e métodos que você pode acessar:
// Static method on type Byte.
byte b = Byte.MaxValue;
Mas você declarar e atribuir valores a eles como se fossem os tipos de não-agregada simples:
byte num = 0xA;
int i = 5;
char c = 'Z';
Tipos de valor são lacrado, que significa, por exemplo, se você não pode derivar um tipo de System.Int32, e não é possível definir uma struct herdar de qualquer classe definida pelo usuário ou struct, porque uma struct só pode herdar de System.ValueType.No entanto, uma struct pode implementar uma ou mais interfaces.Você pode converter um tipo de struct para um tipo de interface; Isso faz com que uma boxing operação para quebrar o struct dentro de um objeto do tipo de referência no heap gerenciado.Operações de conversão boxing ocorrem quando você passa um tipo de valor para um método que usa um System.Object como um parâmetro de entrada.Para obter mais informações, consulte Boxing e Unboxing (C# Guia de programação).
Você pode usar o struct palavra-chave para criar seus próprios tipos de valor personalizado.Normalmente, uma struct serve como um recipiente para um pequeno conjunto de variáveis relacionadas, conforme mostrado no exemplo a seguir:
public struct CoOrds
{
public int x, y;
public CoOrds(int p1, int p2)
{
x = p1;
y = p2;
}
}
Para obter mais informações sobre estruturas, consulte Structs (guia de programação do C#).Para obter mais informações sobre tipos de valor na .NET Framework, consulte Common Type System.
A outra categoria de tipos de valor é enum.Um enum define um conjunto de constantes nomeadas de integrais.Por exemplo, o System.IO.FileMode enumeração na.NET Framework class library contém um conjunto de inteiros constantes nomeados que especificam como um arquivo deve ser aberto.Ele é definido como mostrado no exemplo a seguir:
public enum FileMode
{
CreateNew = 1,
Create = 2,
Open = 3,
OpenOrCreate = 4,
Truncate = 5,
Append = 6,
}
O System.IO.FileMode.Create a constante tem um valor de 2.No entanto, o nome é muito mais significativo para os humanos lendo o código-fonte e, pelo que motivo que ele é melhor usar enumerações em vez de números literais constantes.Para obter mais informações, consulte System.IO.FileMode.
Todos os enums herdar de System.Enum, que herda de System.ValueType.Também aplicam todas as regras que se aplicam às structs enums.Para obter mais informações sobre as enumerações, consulte Tipos de enumeração (guia de programação do C#).
Tipos de referência
Um tipo que é definido como um classe, delegar, matriz, ou interface é um tipo de referência.Em tempo de execução, quando você declara uma variável de um tipo de referência, a variável contém o valor Nulo até que você cria uma instância do objeto explicitamente usando a nova operador, ou atribuir-lhe um objeto que tenha sido criado em outro lugar usandonew, as shown in the following example:
MyClass mc = new MyClass();
MyClass mc2 = mc;
Uma interface deve ser inicializada em conjunto com um objeto de classe que implementa a ele.Se MyClass implementa IMyInterface, você cria uma instância de IMyInterface conforme mostrado no exemplo a seguir:
IMyInterface iface = new MyClass();
Quando o objeto é criado, a memória é alocada no heap gerenciado e a variável armazena apenas uma referência para o local do objeto.Tipos no heap gerenciado requerem sobrecarga quando eles são alocados e quando eles são recuperados pela funcionalidade de gerenciamento automático de memória do CLR, que é conhecido como coleta de lixo.No entanto, coleta de lixo é também altamente otimizada e na maioria dos cenários não cria um problema de desempenho.Para obter mais informações sobre a coleta de lixo, consulte Gerenciamento automático de memória.
Todas as matrizes são tipos de referência, mesmo que seus elementos são tipos de valor.Arrays implicitamente derivam de System.Array classe, mas você declarar e usá-los com a sintaxe simplificada que é fornecida pela C#, conforme mostrado no exemplo a seguir:
// 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;
Tipos de referência totalmente oferecem suporte a herança.Quando você cria uma classe, você pode herdar de qualquer outra interface ou classe que não está definido como lacrado, e outras classes podem herdar de sua classe e substituem os métodos virtuais.Para obter mais informações sobre como criar suas próprias classes, consulte Classes e estruturas (guia de programação do C#).Para obter mais informações sobre herança e métodos virtuais, consulte Herança (guia de programação do C#).
Tipos de valores literais
C#, valores literais recebem um tipo de compilador.Você pode especificar como um literal numérico deverá ser digitado, anexando uma letra ao final do número.Por exemplo, para especificar que o valor 4.56 deve ser tratado como uma float, acrescente um "f" ou "F" após o número: 4.56f.Se nenhuma letra for anexada, o compilador irá inferir um tipo para o literal.Para obter mais informações sobre quais os tipos podem ser especificados com os sufixos de letra, consulte as páginas de referência para tipos individuais em Tipos de valor (referência de C#).
Porque literais são digitadas e todos os tipos derivam, por fim, da System.Object, você pode escrever e compilar o código, como a seguir:
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éricos
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á quando ele cria uma instância do tipo.Esses tipos são chamados de tipos genéricos.Por exemplo, o.NET Framework equivalente System.Collections.Generic.List<T> tem um parâmetro de tipo que, por convenção, receberá o nome t.Quando você cria uma instância do tipo, você pode especificar o tipo dos objetos que a lista conterá, por exemplo, a seqüência de caracteres:
List<string> strings = new List<string>();
O uso do parâmetro de tipo torna possível reutilizar a mesma classe para conter qualquer tipo de elemento, sem precisar converter cada elemento a ser objeto.São chamados de classes de coleção genérica coleções com rigidez de tipos como o compilador sabe o tipo específico de elementos da coleção e pode gerar um erro em tempo de compilação se, por exemplo, você tentar adicionar um número inteiro para o strings o objeto no exemplo anterior.Para obter mais informações, consulte Genéricos (guia de programação do C#).
Tipos implícitos, tipos anônimos e tipos anuláveis
Conforme mencionado anteriormente, você implicitamente pode digitar uma variável local (mas não os membros de classe), usando o var palavra-chave.A variável ainda recebe um tipo em tempo de compilação, mas o tipo é fornecido pelo compilador.Para obter mais informações, consulte Variáveis de locais digitadas implicitamente (C# Guia de programação).
Em alguns casos, é inconveniente criar um tipo nomeado para conjuntos simples de valores relacionados que você pretende armazenar ou passar fora dos limites de método.Você pode criar tipos anônimos para essa finalidade.Para obter mais informações, consulte Tipos anônimos (guia de programação do C#).
Tipos de valor comum não podem ter um valor de Nulo.No entanto, você pode criar tipos de valor anulável, fixar um ? após o tipo.Por exemplo, int? é um int tipo também pode ter o valor Nulo.No CTS, tipos anuláveis são instâncias do tipo struct genérico System.Nullable<T>.Tipos anuláveis são especialmente úteis quando você está passando dados para e de bancos de dados no qual os valores numéricos podem ser nulos.Para obter mais informações, consulte Tipos anuláveis (guia de programação do C#).
Seções relacionadas
Para obter mais informações, consulte os seguintes tópicos:
Especificação da linguagem C#
Para obter mais informações, consulte Especificação de linguagem do C# A especificação da linguagem é a fonte definitiva para a sintaxe e o uso da linguagem C#.
Consulte também
Referência
Tipos de dados comparados em vários idiomas
Tabela de tipos integral (referência de C#)