Coerções e conversões de tipo (Guia de Programação em C#)Casting and type conversions (C# Programming Guide)

Como o C# é tipado estaticamente no tempo de compilação, depois que uma variável é declarada, ela não pode ser declarada novamente ou atribuída a um valor de outro tipo, a menos que esse tipo possa ser convertido implicitamente no tipo da variável.Because C# is statically-typed at compile time, after a variable is declared, it cannot be declared again or assigned a value of another type unless that type is implicitly convertible to the variable's type. Por exemplo, a string não pode ser convertida implicitamente em int.For example, the string cannot be implicitly converted to int. Portanto, depois de declarar i como um int, não é possível atribuir a cadeia de caracteres "Hello" a ele, como mostra o código a seguir:Therefore, after you declare i as an int, you cannot assign the string "Hello" to it, as the following code shows:

int i;

// error CS0029: Cannot implicitly convert type 'string' to 'int'
i = "Hello";

No entanto, às vezes é necessário copiar um valor para uma variável ou um parâmetro de método de outro tipo.However, you might sometimes need to copy a value into a variable or method parameter of another type. Por exemplo, você pode ter que passar uma variável de inteiro para um método cujo parâmetro é digitado como double.For example, you might have an integer variable that you need to pass to a method whose parameter is typed as double. Ou talvez precise atribuir uma variável de classe a uma variável de um tipo de interface.Or you might need to assign a class variable to a variable of an interface type. Esses tipos de operações são chamados de conversões de tipo.These kinds of operations are called type conversions. No C#, você pode realizar os seguintes tipos de conversões:In C#, you can perform the following kinds of conversions:

  • Conversões implícitas: nenhuma sintaxe especial é necessária porque a conversão sempre é bem sucedido e nenhum dado será perdido.Implicit conversions: No special syntax is required because the conversion always succeeds and no data will be lost. Exemplos incluem conversões de tipos integrais menores para maiores e conversões de classes derivadas para classes base.Examples include conversions from smaller to larger integral types, and conversions from derived classes to base classes.

  • Conversões explícitas (conversão): conversões explícitas exigem uma expressão de conversão.Explicit conversions (casts): Explicit conversions require a cast expression. A conversão é necessária quando as informações podem ser perdidas na conversão ou quando a conversão pode não funcionar por outros motivos.Casting is required when information might be lost in the conversion, or when the conversion might not succeed for other reasons. Exemplos típicos incluem a conversão numérica para um tipo que tem menos precisão ou um intervalo menor e a conversão de uma instância de classe base para uma classe derivada.Typical examples include numeric conversion to a type that has less precision or a smaller range, and conversion of a base-class instance to a derived class.

  • Conversões definidas pelo usuário: as conversões definidas pelo usuário são realizadas por métodos especiais que podem ser definidos para habilitar conversões explícitas e implícitas entre tipos personalizados que não têm uma relação de classe base/classe derivada.User-defined conversions: User-defined conversions are performed by special methods that you can define to enable explicit and implicit conversions between custom types that do not have a base class–derived class relationship. Para saber mais, confira Operadores de conversão definidos pelo usuário.For more information, see User-defined conversion operators.

  • Conversões com classes auxiliares: para converter entre tipos não compatíveis, assim como inteiros e objetos System.DateTime, ou cadeias de caracteres hexadecimais e matrizes de bytes, você pode usar a classe System.BitConverter, a classe System.Convert e os métodos Parse dos tipos numéricos internos, tais como Int32.Parse.Conversions with helper classes: To convert between non-compatible types, such as integers and System.DateTime objects, or hexadecimal strings and byte arrays, you can use the System.BitConverter class, the System.Convert class, and the Parse methods of the built-in numeric types, such as Int32.Parse. Para obter mais informações, consulte como converter uma matriz de bytes em um int, como converter uma cadeia de caracteres em um númeroe como converter entre cadeias de caracteres hexadecimais e tipos numéricos.For more information, see How to convert a byte array to an int, How to convert a string to a number, and How to convert between hexadecimal strings and numeric types.

Conversões implícitasImplicit conversions

Para tipos numéricos internos, uma conversão implícita poderá ser feita quando o valor a ser armazenado puder se ajustar à variável sem ser truncado ou arredondado.For built-in numeric types, an implicit conversion can be made when the value to be stored can fit into the variable without being truncated or rounded off. Para tipos integrais, isso significa que o intervalo do tipo de origem é um subconjunto apropriado do intervalo para o tipo de destino.For integral types, this means the range of the source type is a proper subset of the range for the target type. Por exemplo, uma variável do tipo long (inteiro de 64 bits) pode armazenar qualquer valor que um int (inteiro de 32 bits) pode armazenar.For example, a variable of type long (64-bit integer) can store any value that an int (32-bit integer) can store. No exemplo a seguir, o compilador converte implicitamente o valor de num à direita em um tipo long antes de atribuí-lo a bigNum.In the following example, the compiler implicitly converts the value of num on the right to a type long before assigning it to bigNum.

// Implicit conversion. A long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;

Para obter uma lista completa de todas as conversões numéricas implícitas, consulte a seção conversões numéricas implícitas do artigo sobre conversões numéricas internas .For a complete list of all implicit numeric conversions, see the Implicit numeric conversions section of the Built-in numeric conversions article.

Para tipos de referência, uma conversão implícita sempre existe de uma classe para qualquer uma das suas interfaces ou classes base diretas ou indiretas.For reference types, an implicit conversion always exists from a class to any one of its direct or indirect base classes or interfaces. Nenhuma sintaxe especial é necessária porque uma classe derivada sempre contém todos os membros de uma classe base.No special syntax is necessary because a derived class always contains all the members of a base class.

Derived d = new Derived();

// Always OK.
Base b = d;

Conversões explícitasExplicit conversions

No entanto, se uma conversão não puder ser realizada sem o risco de perda de informações, o compilador exigirá que você execute uma conversão explícita, que é chamada de cast.However, if a conversion cannot be made without a risk of losing information, the compiler requires that you perform an explicit conversion, which is called a cast. Uma conversão é uma maneira de informar explicitamente ao compilador que você pretende fazer a conversão e que você está ciente de que a perda de dados pode ocorrer, ou a conversão pode falhar em tempo de execução.A cast is a way of explicitly informing the compiler that you intend to make the conversion and that you are aware that data loss might occur, or the cast may fail at runtime. Para executar uma conversão, especifique entre parênteses o tipo para o qual você está convertendo, na frente do valor ou da variável a ser convertida.To perform a cast, specify the type that you are casting to in parentheses in front of the value or variable to be converted. O programa a seguir converte um Double em um int. O programa não será compilado sem a conversão.The following program casts a double to an int. The program will not compile without the cast.

class Test
{
    static void Main()
    {
        double x = 1234.7;
        int a;
        // Cast double to int.
        a = (int)x;
        System.Console.WriteLine(a);
    }
}
// Output: 1234

Para obter uma lista completa de conversões numéricas explícitas com suporte, consulte a seção de conversões numéricas explícitas do artigo embutir conversões numéricas .For a complete list of supported explicit numeric conversions, see the Explicit numeric conversions section of the Built-in numeric conversions article.

Para tipos de referência, uma conversão explícita será necessária se você precisar converter de um tipo base para um tipo derivado:For reference types, an explicit cast is required if you need to convert from a base type to a derived type:

// Create a new derived type.
Giraffe g = new Giraffe();

// Implicit conversion to base type is safe.
Animal a = g;

// Explicit conversion is required to cast back
// to derived type. Note: This will compile but will
// throw an exception at run time if the right-side
// object is not in fact a Giraffe.
Giraffe g2 = (Giraffe)a;

Uma operação de conversão entre tipos de referência não altera o tipo de tempo de execução do objeto subjacente. Ela apenas altera o tipo do valor que está sendo usado como uma referência a esse objeto.A cast operation between reference types does not change the run-time type of the underlying object; it only changes the type of the value that is being used as a reference to that object. Para obter mais informações, consulte Polimorfismo.For more information, see Polymorphism.

Exceções de conversão de tipo em tempo de execuçãoType conversion exceptions at run time

Em algumas conversões de tipo de referência, o compilador não poderá determinar se uma conversão será válida.In some reference type conversions, the compiler cannot determine whether a cast will be valid. É possível que uma operação de conversão que é compilada corretamente falhe em tempo de execução.It is possible for a cast operation that compiles correctly to fail at run time. Conforme mostrado no exemplo a seguir, um tipo de conversão que falha em tempo de execução fará com que uma InvalidCastException seja lançada.As shown in the following example, a type cast that fails at run time will cause an InvalidCastException to be thrown.

class Animal
{
    public void Eat() => System.Console.WriteLine("Eating.");

    public override string ToString() => "I am an animal.";
}

class Reptile : Animal { }
class Mammal : Animal { }

class UnSafeCast
{
    static void Main()
    {
        Test(new Mammal());

        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }

    static void Test(Animal a)
    {
        // System.InvalidCastException at run time
        // Unable to cast object of type 'Mammal' to type 'Reptile'
        Reptile r = (Reptile)a;
    }
}

O Test método tem um Animal parâmetro, portanto, converter explicitamente o argumento a para um Reptile faz uma suposição perigosa.The Test method has an Animal parameter, thus explicitly casting the argument a to a Reptile makes a dangerous assumption. É mais seguro não fazer suposições, mas sim verificar o tipo.It is safer to not make assumptions, but rather check the type. O C# fornece o operador is para habilitar o teste de compatibilidade antes de realmente executar uma conversão.C# provides the is operator to enable you to test for compatibility before actually performing a cast. Para obter mais informações, consulte como converter com segurança usando correspondência de padrões e os operadores as e is.For more information, see How to safely cast using pattern matching and the as and is operators.

Especificação da linguagem C#C# language specification

Para saber mais, confira a seção Conversões da Especificação da linguagem C#.For more information, see the Conversions section of the C# language specification.

Confira tambémSee also