Why need boxing and unboxing

Why do we need boxing and unboxing in C#?
http://stackoverflow.com/questions/2111857/why-do-we-need-boxing-and-unboxing-in-c

 

struct Point
{
public int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
public override string ToString()
{
return String.Format(“{0} {1}”, this.x, this.y);
}
}
class Point2
{
public int x, y;
public Point2(int x, int y)
{
this.x = x;
this.y = y;
}

public override string ToString()
{
return String.Format(“{0} {1}”, this.x, this.y);
}
class Program
{
static void Print(object o)
{
Console.WriteLine(o);
}
static void Main(string[] args)
{
int x = 4;
Print(x); // boxing (int=>object)
double y = 3.2;
Print(y); // boxing (double=>object)
char z = ‘n’;
Print(z); // boxing (char=>object)
double e = 2.718281828459045;
object o1 = e; // boxing (double=>object)
object o2 = e; // boxing (double=>object)
Console.WriteLine
(o1 == o2); // False (o1과 o2는 서로 다른 메모리에 데이타 복사본 저장)
Point p3 = new Point(1, 1);
Print(p3); // boxing (struct=>object)
object o3 = p3; // boxing (struct=>object)
p3.x = 2;
//((Point)o3).x = 4;
// CS0445 Cannot modify the result of an unboxing conversion 
Console.WriteLine(((Point)o3).x); // 1  unboxing(object=>struct) o3.x=1 (o3는 박싱된 복사본 p3에의해 데이터 안바뀜)
Point2 p4 = new Point2(1, 1);
Print(p4); // boxing 아님
object o4 = p4; // boxing 아님
p4.x = 2;
Print(p4); // upcasting(Point2 class=>object) 2 1
((Point2)o4).x = 4; // downcasting(object=>Point2 class) o4.x=2 (class는 reference type이므로 o4는 p4에의해 데이터가 바뀜)
Console.WriteLine(p4); // p4.ToString()호출 4 1
}
}

Boxing과 Unboxing을 최소화하라

Boxing은 값 형식 (value type)을 참조 형식 (reference type)으로 변경하는 것이다.
Boxing을 수행하면 힙 상에 새로운 reference type 객체가 생성되고 value type의 객체가 가지고 있던 값이 reference type 객체 내부로 복사된다.
새로 생성된 reference type 객체는 내부적으로 value type 객체의 복사본을 포함하고, value type에서 제공하였던 interface를 그대로 재구현한다.

Unboxing은 참조 형식 (reference type)을 값 형식 (value type)으로 변경하는 것이다.
만약 reference type 객체 내부에 포함된 value type 객체의 값을 얻고자 시도하면 복사본을 만들어서 돌려준다.

Console.WriteLine(“Numbers: {0}, {1}, {2}”, 10, 20, 30);
Console.WriteLine()은 System.Object의 배열을 인자로 받는데, 정수들은 모두 value type이기때문에 value type의 인자로 전달하기 위해서는 reference type으로 boxing이 수행된다.
Boxing과 Unboxing 동작은 필요시 자동적으로 일어나며, 이 과정에서 컴파일러는 어떠한 경고도 발생시키지 않는다. WriteLine(…)을 호출할 때에는, 아래와 같이 value type을 string type instance로 변경하는 것이 좋다.
Console.WriteLine(“Numbers: {0}, {1}, {2}”, 10.ToString(), 20.ToString(), 30.ToString());
이 코드는 string type을 사용하기 때문에 value type들은 더이상 System.Object 로 변경되지 않는다.