ice rabbit programming

[C#] C#의 자료형3 - Casting과 Boxing 본문

Development/C#

[C#] C#의 자료형3 - Casting과 Boxing

판교토끼 2020. 4. 18. 23:14

지난 글에 이어서 오늘은 Casting과 Boxing/Unboxing에 대해 정리하려 한다.

Casting - 묵시적, 명시적

다른 언어를 다루어보신 분들이라면 Casting, 즉 형변환의 개념은 익숙할 것이다.

형변환에는 묵시적(암시적) 형변환과 명시적 형변환이 있다. 말 그대로 명시적은 프로그래머가 코드 상에 적어주는 것이고, 묵시적은 그렇지 않다.

int number = 5;
double pi = 3.14;
number = pi; // 묵시적 형변환, 데이터 손실 발생!!

가장 전형적인 예제는 double을 int에 넣는 예제일 것이다. 위 코드에서는 double 변수를 int에 묵시적으로 넣고 있고, 이 때 데이터 손실이 발생한다. C++에서는 묵시적 형변환 시에 데이터의 손실이 있든 없든, 허용이 된다(절삭).

하지만 C#에서는 묵시적 형변환 시에 데이터의 손실이 있으면 에러가 발생한다. 다만 손실이 없는 경우(int->double)에는 묵시적 형변환이 가능하다.
데이터의 손실이 있더라도 명시적으로 캐스팅하는 것은 가능하다.

int num=5;
double pi=3.14;
num=pi; // 묵시적, 데이터 손실 발생, error

int num2=5;
double pi2=3.14;
pi=num // 묵시적, 손실 없음, ok

int num3=5;
double pi=3.14;
num=(int)pi; // 명시적, ok

다만 int나 double과 같이 기본 자료형이 아닌 사용자 정의 타입(struct, class)으로 명시적 캐스팅을 원할 경우에는, 연산자 오버로딩으로 이를 구현할 수 있다.

Casting - is, as

is 연산자와 as 연산자가 있다. 이 개념은 필자가 느끼기에는 보다 더 직관적으로 사용할 수 있는 것 같다.

is 연산자는 DataType을 검사한다. null 검사까지 포함된 개념이다.
as 연산자는 Casting을 해 주고, 실패 시에는 null을 반환한다. 이 때, as는 연산자 오버로딩으로 만든 변환 연산자가 호출되지 않는다.

void foo(object a) {
    if(a is Dog)
    	var d = a as Dog;
}

as 연산자는 실패 시에 null을 반환하지만, (Dog) a;와 같은 명시적 Casting은 실패 시에 Exception이 발생한다.

Boxing & Unboxing

value type은 stack에 저장되고, reference type은 heap에 저장되며 heap에 있는 값만 가리킬 수 있기 때문에 발생하는 이슈이다.

무슨 말이냐면, Reference type의 변수가 value type을 가리키게 될 경우에 Reference type은 heap에 있는 값만 가리킬 수 있기 때문에 value를 headp에 복사해온 후에 가리킨다. 이를 Boxing이라고 한다.

반면에, Heap에 있는 value를 value type은 가질 수 없으니, stack에 복사해서 가져오는 것이다. 이를 Unboxing이라고 한다.

만약 Boxing->Unboxing의 형태로 일어나게 되면, 최초 출발 값이 동일함에도 복사가 두 번 일어나게 되는 것이다.

이러한 일은 피하는 것이 좋은데, Generic Interface를 구현함으로써 이를 막을 수 있다.

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

[C#] 메소드  (0) 2020.05.04
[C#] 배열(Array)  (0) 2020.04.30
[C#] C#의 자료형2 - Value vs Reference, Nullable  (2) 2020.04.15
[C#] C#의 자료형  (0) 2020.04.10
[C#] C#을 시작하며, .NET Framework  (0) 2020.04.09