C#의 이상한 정수 캐스팅

  • Post author:
  • Post category:
  • Post comments:5 Comments
  • Post last modified:April 20, 2009

간단한 정수 캐스팅 하나!

long longValue = 1;
int intValue = longValue;

이 코드는 컴파일러 오류를 발생시킨다.

오류 CS0266: 암시적으로 ‘long’ 형식을 ‘int’ 형식으로 변환할 수 없습니다. 명시적 변환이 있습니다. 캐스트가 있는지 확인하십시오.

역시 간단한 상황!

var longList = new List<long> {1, 2, 3};
foreach(int intValue in longList)
{

}

어이없게도 컴파일 된다. 이 때문에 응용프로그램을 실행한 후에야 버그를 발견했다. 왜 이런 걸까?

This Post Has 5 Comments

  1. kj

    foreach는 dynamic type casting을 이용하는 걸까요? ^^;;
    그래도 foreach가 닷넷에서 제일 빠른 loop라고 들었는데.. ^^;; 설마.. 그럴까 싶기도 하고.. ㅡㅡ;;

  2. 최재훈

    글쎄요. 누가 속시원히 설명 좀 해주면 좋겠습니다. 큭.

  3. webtk

    제가 기억하는 바로는 foreach 구문은 컴파일 시 내부적으로 캐스트 연산자를 사용한 구문으로 바뀌기 때문입니다. (아래는 Effective C#에서 발췌)

    // foreach 구문
    IEnumerable collection = GetCollection();
    foreach (Mytype t in collection)
    {
      t.DoStuff();
    }

    // 실제 내부적으로 작동하는 코드
    IEnumerator it = collection.GetEnumerator();
    while (it.MoveNext())
    {
      Mytype t = (Mytype)it.Current;
      t.DoStuff();
    }

    이렇게 캐스트를 사용하는 이유는 형식의 종류(값,참조)에 독립적이어야 하기 때문입니다. 그러니 컴파일은 정상적으로 되더라도 런타임에서는 오류가 발생할 수도 있습니다.
    (“C# in Depth”에서도 Implicit casting in foreach loops over generic collections 라는 장(1.1.2)에서 설명을 하네요.)

  4. 최재훈

    정신이 없다 보니 댓글 쓰는 걸 깜박 했습니다.

    음… Effective C#에 그런 내용이 있었나요? 예전에 읽을 땐 직접 겪은 일이 아니라 어물쩍 넘어갔나 보네요.

  5. 김헌수

    for 문으로 배열에 접근하는 경우 범위체크가 적용되어 성능이 많이 저하됩니다.
    그런 점에서 foreach 문이 더 빠르다고 할 수 있습니다.
    하지만, for 문의 경우도 조건에 따라서는 C# 옵티마이저가 범위체크를 제거해주는 경우가 있어서 항상 그런 것은 아니구요.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.