일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- dotenv
- vuetify
- security
- docker
- BOJ
- property
- vue.js
- AI
- Python
- C#
- type
- machine learning
- C++
- TypeScript
- 보안
- JavaScript
- condition
- nginx
- Clone
- scss
- VUE
- generic
- webpack
- git
- leetcode
- loop
- bash
- var
- 앙상블
- npm
- Today
- Total
ice rabbit programming
[C#] C#의 자료형3 - Casting과 Boxing 본문
지난 글에 이어서 오늘은 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 |