캐스팅 및 형식 변환(C# 프로그래밍 가이드)Casting and type conversions (C# Programming Guide)

C#은 컴파일 시간에 정적으로 형식화되므로 변수가 선언된 후에는 다시 선언되거나 다른 형식의 값이 할당될 수 없습니다. 단, 형식이 변수의 형식으로 암시적으로 변환될 수 있는 경우는 예외입니다.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. 예를 들어 stringint로 암시적으로 변환될 수 없습니다.For example, the string cannot be implicitly converted to int. 따라서 iint로 선언한 후에는 다음 코드와 같이 문자열 "Hello"를 할당할 수 없습니다.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";

그러나 다른 형식의 변수 또는 메서드 매개 변수에 값을 복사해야 하는 경우도 있습니다.However, you might sometimes need to copy a value into a variable or method parameter of another type. 예를 들어 매개 변수가 double로 형식화된 메서드에 전달해야 하는 정수 변수가 있을 수 있습니다.For example, you might have an integer variable that you need to pass to a method whose parameter is typed as double. 또는 인터페이스 형식의 변수에 클래스 변수를 할당해야 할 수 있습니다.Or you might need to assign a class variable to a variable of an interface type. 이러한 작업을 형식 변환이라고 합니다.These kinds of operations are called type conversions. C#에서는 다음과 같은 변환을 수행할 수 있습니다.In C#, you can perform the following kinds of conversions:

  • 암시적 변환: 변환은 항상 성공하고 데이터가 손실되지 않으므로 특수 구문이 필요하지 않습니다.Implicit conversions: No special syntax is required because the conversion always succeeds and no data will be lost. 예제에는 작은 정수 형식에서 큰 정수 형식으로의 변환 및 파생 클래스에서 기본 클래스로의 변환이 포함됩니다.Examples include conversions from smaller to larger integral types, and conversions from derived classes to base classes.

  • 명시적 변환(캐스트) : 명시적 변환에는 캐스트 식이 필요합니다.Explicit conversions (casts): Explicit conversions require a cast expression. 변환 시 정보가 손실되거나 다른 이유로 변환에 실패할 경우 캐스팅이 필요합니다.Casting is required when information might be lost in the conversion, or when the conversion might not succeed for other reasons. 일반적인 예제에는 숫자를 정밀도가 낮거나 범위가 더 작은 형식으로 변환하는 작업과 기본 클래스 인스턴스를 파생 클래스로 변환하는 작업이 포함됩니다.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.

  • 사용자 정의 변환: 사용자 정의 변환은 기본 클래스-파생 클래스 관계가 없는 사용자 지정 형식 간의 명시적 및 암시적 변환을 사용하도록 정의할 수 있는 특수 메서드를 통해 수행됩니다.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. 자세한 내용은 사용자 정의 변환 연산자를 참조하세요.For more information, see User-defined conversion operators.

  • 도우미 클래스를 사용한 변환: 정수와 System.DateTime 개체, 16진수 문자열과 바이트 배열 등 호환되지 않는 형식 간에 변환하려면 System.BitConverter 클래스, System.Convert 클래스 및 기본 제공 숫자 형식(예: Int32.Parse)의 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. 자세한 내용은 바이트 배열을 int로 변환하는 방법, 문자열을 숫자로 변환하는 방법16진수 문자열과 숫자 형식 간에 변환하는 방법을 참조하세요.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.

암시적 변환Implicit conversions

기본 제공 숫자 형식의 경우 저장되는 값이 잘리거나 반올림되지 않고 변수에 맞출 수 있을 때 암시적 변환을 수행할 수 있습니다.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. 이것은 정수 형식의 경우 소스 형식의 범위가 대상 유형에 대한 범위의 적절한 하위 집합임을 의미합니다.For integral types, this means the range of the source type is a proper subset of the range for the target type. 예를 들어 long 형식의 변수(64비트 정수)는 int(32비트 정수)가 저장할 수 있는 모든 값을 저장할 수 있습니다.For example, a variable of type long (64-bit integer) can store any value that an int (32-bit integer) can store. 다음 예제에서 컴파일러는 오른쪽의 num 값을 long 형식으로 암시적으로 변환한 후 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;

모든 암시적 숫자 변환의 전체 목록은 기본 제공 숫자 변환 문서의 암시적 숫자 변환 섹션을 참조하세요.For a complete list of all implicit numeric conversions, see the Implicit numeric conversions section of the Built-in numeric conversions article.

참조 형식의 경우 클래스에서 직접 또는 간접 기본 클래스나 인터페이스로의 암시적 변환이 항상 존재합니다.For reference types, an implicit conversion always exists from a class to any one of its direct or indirect base classes or interfaces. 파생 클래스에 항상 기본 클래스의 모든 멤버가 포함되므로 특수 구문이 필요하지 않습니다.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;

명시적 변환Explicit conversions

그러나 변환을 수행할 때 정보 손실의 위험이 있는 경우에는 컴파일러에서 캐스트라는 명시적 변환을 수행해야 합니다.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. 캐스트는 변환을 수행하고자 하고 데이터 손실이 발생하거나 런타임에 캐스트가 실패할 가능성을 알고 있음을 컴파일러에 명시적으로 알리는 방법입니다.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. 캐스트를 수행하려면 변환할 값 또는 변수 앞에 캐스트할 형식을 괄호 안에 지정합니다.To perform a cast, specify the type that you are casting to in parentheses in front of the value or variable to be converted. 다음 프로그램은 doubleint로 캐스트합니다. 캐스트가 없으면 프로그램이 컴파일되지 않습니다.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

지원되는 명시적 숫자 변환의 전체 목록은 기본 제공 숫자 변환 문서의 명시적 숫자 변환 섹션을 참조하세요.For a complete list of supported explicit numeric conversions, see the Explicit numeric conversions section of the Built-in numeric conversions article.

참조 형식의 경우 기본 형식에서 파생 형식으로 변환해야 할 경우에는 명시적 캐스트가 필요합니다.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;

참조 형식 간 캐스트 작업은 기본 개체의 런타임 형식을 변경하지 않습니다. 참조로 사용되는 값의 형식을 해당 개체로만 변경합니다.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. 자세한 내용은 다형성을 참조하세요.For more information, see Polymorphism.

런타임의 형식 변환 예외Type conversion exceptions at run time

일부 참조 형식 변환 시에는 컴파일러에서 캐스트가 유효한지 여부를 확인할 수 없습니다.In some reference type conversions, the compiler cannot determine whether a cast will be valid. 제대로 컴파일되는 캐스트 작업이 런타임에 실패할 수 있습니다.It is possible for a cast operation that compiles correctly to fail at run time. 다음 예제와 같이 런타임에 형식 캐스트가 실패하면 InvalidCastException이 throw됩니다.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;
    }
}

Test 메서드에 Animal 매개 변수가 있으므로 인수 aReptile로 명시적으로 캐스팅하면 위험한 가정이 생성됩니다.The Test method has an Animal parameter, thus explicitly casting the argument a to a Reptile makes a dangerous assumption. 가정을 생성하지 않고 형식을 확인하는 것이 더 안전합니다.It is safer to not make assumptions, but rather check the type. C#에서는 실제로 캐스트를 수행하기 전에 호환성을 테스트할 수 있도록 is 연산자를 제공합니다.C# provides the is operator to enable you to test for compatibility before actually performing a cast. 자세한 내용은 패턴 일치, as 및 is 연산자를 사용하여 안전하게 캐스트하는 방법을 참조하세요.For more information, see How to safely cast using pattern matching and the as and is operators.

C# 언어 사양C# language specification

자세한 내용은 C# 언어 사양전환 섹션을 참조하세요.For more information, see the Conversions section of the C# language specification.

참조See also