본문 바로가기
Language/C#

c# Boxing, UnBoxing

by ninanio3 2011. 12. 30.

이제 조금씩 단계가 높아지고 있다. 배열공부를 하다 보니 이런저런 Method를 쓰게 되고 다시 예전에 봤던 소설같은 c#을 보게 되었다. 역시, 기초가 중요하다. 다른 이들의 블로그를 봐도 뭔말인지 이해못하는 이심정은... ㅠㅠ

Boxing UnBoxing은 값타입과 참조타입을 바꿔주는데 쓰이는 개념이다. c#에서는 서로 다른 성질의 데이터타입인 값타입과 참조타입으로 나뉘는데, 두 개가 공존을 한다. 일례로, Object형은 참조타입이다. 그러면서 값타입도 가지고 있다. Object형은 최상위 클래스이기 때문에 업캐스팅의 원리에 의해서 모든 객체는 Object형으로 반환될 수 있다. 그런데 내가 써본 바로는 Object형으로 업캐스팅하면 에러가 났다. 클래스에 파라미터를 실어 나를에나, 리턴값이나, 타입이 이미 지정이 되어 있는 경우가 대부분이기 때문이다.

Boxing
Boxing이란 값타입을 참조타입으로 변환하는 것을 말한다.

Boxing을 하는 기본적인 방법은 값타입을 객체화하기 위한 메모리를 힙에 생성한 후 값타입에 들어있는 값을 복사하는 것이다.
1. 값타입 변수를 객체화하기 위한 메모리를 힙 영역에 생성한다. 이 공간을 Box라고 한다.
2. 값타입에 있는 값을 힙에 생성한 Box로 복사한다.
3. 참조타입 변수에 참조값을 할당한다.

말로하면 원래 어렵다. 예제로 하자.

int Boxing = 123;
object o = Boxing;  //Boxing이 발생한다.

int 의 값타입이 Object의 참조타입으로 변했다. 값도 복사가 되면서 Boxing이 되었다. 사소한 코드같지만... 이 한 줄이 나중에 에러가 나느냐 안나느냐를 가른다. ㅠㅠ


UnBoxing
UnBoxing은 참조타입을 다시 값타입으로 변환하는 것을 말한다. Boxing과 반대되는 개념이다. UnBoxing 실행과정은
1. 해당 객체가 지정한 값타입을 Boxing한 값인지 확인
2. Boxing된 객체라면 객체의 값을 값타입 변수에 복사
3. Boxing한 메모리와 UnBoxing한 메모리 두 개가 존재.

결국... 메모리가 두 개가 상주하게 된다. 별 개의 메모리이다.

말로 하면 원래 어렵다고 했다. 예제로 하자.
int Boxing = 123;
object o = Boxing; //Boxing이 발생한다.
int UnBoxing = (int)o;  //UnBoxing이 발생한다.

1. UnBoxing은 명시적으로 이루어져야 하고,
2. Boxing된 변수의 공간과는 별도의 메모리 공간에 값이 저장된다. 새로운 값이 생긴다는 뜻이다.
3. Boxing된 데이터 타입에 맞는 형으로 형변환을 해주어야 한다. int형이 Object로 Boxing했다면 다시 int형으로 UnBoxing해주어야 한다. 그렇지 않으면 System.InvalidCastException 에러가 발생한다.
참고로, UnBoxing이 많아지면 과부하가 걸린다.

 

 

아래는 코드다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HEK_Exer;
using System.Collections;

namespace HEK_Exercise
{
    public class Program
    {
        public static void Main()
        {
            // boxing unboxing
            int nums = 123;
            object on = nums;
            int count = (int)on;

            BitOper bits = new BitOper();
            bits.TenToBinary(nums);
            string str = bits.TenToBinary();
            Console.WriteLine("{0}을 2진수로 : {1}", nums, str);
        }       
    }
}

/*
 * 이 문제의 출처는 c#프로그래밍 기본기 익히기
 * , 정보문화사, 조효은지음
 */



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace HEK_Exer
{
    public class BitOper
    {
        public const int MASK02 = 1;
        private ArrayList twoList = new ArrayList();

        //10진수를 2진수로 변환
        public void TenToBinary(int n)
        {
            twoList.Clear();
            for (int i = 0; i < 32; i++)
            {
                //twoList[i] = n & MASK02는 바꾸기
                //앞쪽으로 붙이기, add는 뒤쪽에 붙이기
                twoList.Insert(0, n & MASK02);
                n >>= 1; //쉬프트 연산은 음수, 양수 무관
            }
        }
        // overloading

        public string TenToBinary()
        {
            string str = string.Empty;
            int count = twoList.IndexOf(1);
            //Console.WriteLine(count);
            // 숫자 0, -0은 count -> -1
            if (count > 0)
            {
                twoList.RemoveRange(0, count);
            }
            for (int i = 0; i < twoList.Count; i++)
            {
                str += (int)twoList[i]; //언박싱
            }
            return str;
        }
    }
}

'Language > C#' 카테고리의 다른 글

c# parsing  (0) 2012.01.02
c# xml 파일 파싱하기  (2) 2011.12.30
c# 배열의 개념이 들어간 버블정렬  (0) 2011.12.24
c# do while문  (0) 2011.12.24
c# while문의 사용  (0) 2011.12.24