값 타입은 주로 값을 저장할 때 쓰는 저장소이며 다형적(polymorphic)이지 못하다.
반면에 .NET Framework는 모든 타입의 최상위 타입을 참조 타입인 System.Object로 정의하고 있다.
이 두 가지는 서로 양립할 수 없는 것처럼 보인다. 하지만 .NET Framework는 박싱과 언박싱이라는
방법을 통해서 이 두 가지 서로 다른 타입을 이어준다.
박싱이란 값 타입의 객체를 타입이 정해져 있지 않은 임의의 참조 타입 내부에 포함시키는 방법이다.
이를 이용하면 참조 타입이 필요한 경우에도 값 타입을 쓸 수 있다.
언박싱이란 반대로 박싱되어 있는 참조 타입의 객체로부터 값 타입 객체의 복사본을 가져오는 방법
이다. 박싱과 언박싱은 System.Object 타입이나 인터페이스 타입이 필요한 곳에서 값 타입을
사용하기 위해 반드시 필요한 메커니즘이다. 하지만 박싱과 언박싱은 성능에 좋지 않은 영향을
미친다. 때로는 박싱과 언박싱을 수행하는 과정에서 임시 객체가 생성되기도 하는데, 간혹 이로 인해
예상치 못한 버그가 발생하기도 한다. 따라서 박싱과 언박싱은 가능한 한 피하는 것이 좋다.
다시 말하지만 박싱은 값 타입을 참조 타입으로 변경한다. 이 과정에서 새롭게 생성된 참조 타입의
객체는 힙에 생성되며, 값 타입의 복사본이 새롭게 생성된 객체 내부에 저장된다.
대부분의 경우 .NET 2.0에 추가된 제네릭 클래스와 제네릭 메서드를 사용하면 박싱과 언박싱을 피할
수 있다. 제네릭 관련 기능을 활용하면 값 타임 객체에 대한 불필요한 박싱 작업이 수행되지 않도록
코드를 작성할 수 있다는 것이다. 하지만 .NET Framework의 도처에는 여전히 System.Object 타입의
객체를 요구하는 경우가 있으며, 이러한 API들은 여전히 박싱과 언박싱 작업을 수행한다.