Share via


컴파일러 오류 CS0029

업데이트: 2007년 11월

오류 메시지

암시적으로 'type' 형식을 'type' 형식으로 변환할 수 없습니다.
Cannot implicitly convert type 'type' to 'type'

컴파일러에는 명시적 변환이 필요합니다. 예를 들어, r-vaule를 캐스팅하여 l-value와 동일한 형식으로 만들거나 변환 루틴을 제공하여 특정 연산자 오버로드를 지원해야 합니다.

한 형식의 변수를 다른 형식의 변수에 할당하면 변환이 발생하게 됩니다. 서로 다른 형식의 변수 사이에 할당을 수행하면 컴파일러는 할당 연산자의 오른쪽 변수의 형식을 할당 연산자의 왼쪽 변수의 형식으로 변환합니다. 다음과 같은 코드에서

int i = 50;
long lng = 100;
i = lng;

i = lng;은 할당을 수행합니다. 하지만 할당 연산자의 왼쪽 및 오른쪽 변수의 데이터 형식이 일치하지 않습니다. 할당을 수행하기 전에 컴파일러는 암시적으로 long 형식인 lng 변수를 int로 변환합니다. 컴파일러에게 이 변환을 수행하도록 지시하는 코드가 없기 때문에 이것은 암시적입니다. 이 코드의 문제는 이 변환이 축소 변환이고, 컴파일러에서는 데이터 손실의 가능성이 있기 때문에 암시적 축소 변환을 허용하지 않는다는 것입니다.

축소 변환은 원래 데이터 형식보다 메모리의 저장 공간을 적게 차지하는 데이터 형식으로 변환할 때 발생합니다. 예를 들어, long을 int로 변환하는 것은 축소 변환입니다. long은 8바이트의 메모리를 차지하는 반면 int는 4바이트를 차지합니다. 데이터 손실이 일어나는 방식을 보기 위해 다음 샘플을 참조하십시오.

int i = 50;
long lng = 3147483647;
i = lng;

값이 너무 커서 i 변수에 저장될 수 없는 값이 lng 변수에 들어 있습니다. 이 값을 int 형식으로 변환하려 할 경우 데이터의 일부를 잃게 되며 변환된 값은 변환 전의 값과 같지 않게 됩니다.

확대 변환은 축소 변환과 반대입니다. 확대 변환은 원래 데이터 형식보다 메모리의 저장 공간을 많이 차지하는 데이터 형식으로 변환하는 것입니다. 다음은 확대 변환의 예제입니다.

int i = 50;
long lng = 100;
lng = i;

이 코드 샘플과 첫째 샘플과의 차이점에 유의하십시오. 이번에는 lng 변수가 할당 연산자의 왼쪽에 나타나므로 할당의 대상이 됩니다. 할당을 수행하기 전에 컴파일러는 int 형식의 i 변수를 long 형식으로 암시적으로 변환해야 합니다. 이것은 4바이트의 메모리를 차지하는 형식(int)에서 8바이트의 메모리를 차지하는 형식(long)으로 변환하기 때문에 확대 변환입니다. 암시적 확대 변환은 데이터 손실의 가능성이 없기 때문에 허용됩니다. int에 저장될 수 있는 값은 모두 long에 저장될 수 있습니다.

암시적 축소 변환이 허용되지 않으므로 이 코드를 컴파일하려면 데이터 형식을 명시적으로 변환해야 합니다. 명시적 변환은 캐스팅을 사용하여 수행됩니다. 캐스팅은 한 데이터 형식에서 다른 데이터 형식으로 변환하는 것을 설명하기 위해 C#에서 사용하는 용어입니다. 위의 코드를 컴파일하려면 다음 구문을 사용해야 합니다.

int i = 50;
long lng = 100;
i = (int) lng;   // cast to int

코드의 셋째 줄에서 컴파일러에게 할당을 수행하기 전에 long 형식의 lng 변수를 int로 변환하도록 지시합니다. 축소 변환의 경우 데이터 손실의 가능성이 있음을 명심하십시오. 축소 변환은 주의해서 사용해야 하며 코드가 컴파일되더라도 런타임에 예기치 않은 결과를 얻게 될 수도 있습니다.

지금까지는 값 형식에 대해서만 설명했습니다. 값 형식으로 작업하는 경우 변수에 저장된 데이터를 직접 처리하게 됩니다. 하지만 .NET Framework에는 참조 형식도 있습니다. 참조 형식으로 작업하는 경우 실제 데이터가 아닌 변수에 대한 참조를 처리하게 됩니다. 참조 형식의 예로는 클래스, 인터페이스, 배열 등이 있습니다. 특정 변환이나 적절한 변환 연산자를 구현하도록 컴파일러가 허용하지 않으면 암시적이든 명시적이든 한 참조 형식을 다른 참조 형식으로 변환할 수 없습니다.

다음 샘플에서는 CS0029 오류가 발생하는 경우를 보여 줍니다.

// CS0029.cs
public class MyInt
{
    private int x = 0;    

    // Uncomment this conversion routine to resolve CS0029
    /*
    public static implicit operator int(MyInt i)
    {
       return i.x;
    }
    */
   

    public static void Main()
   {
      MyInt myInt = new MyInt();
      int i = myInt; // CS0029
   }
}

참고 항목

참조

변환 연산자(C# 프로그래밍 가이드)