언어 심화
15편
GC 가 있는데도 메모리는 샌다
치우는 사람이 있어도 우리가 안 놓으면 안 치워집니다. 가장 흔한 범인은 이벤트입니다.
소멸자는 객체를 한 번 더 살린다
안전망처럼 보이는데 언제 불릴지도 불리기는 할지도 정할 수 없습니다. 붙이면 오히려 늦게 치워집니다.
GC 가 치우지 못하는 것이 있다
힙은 GC 가 알아서 치웁니다. 파일 핸들과 소켓은 아닙니다. using 이 있는 이유입니다.
GC 는 한가할 때 도는 것이 아니다
자리가 모자랄 때 돕니다. 그래서 게임에서는 프레임 한가운데서 돌고, 그 순간 화면이 한 번 걸립니다.
LINQ 는 새로운 문법이 아니다
확장 메서드와 yield 와 람다 셋을 합친 것입니다. 셋을 알면 동작도 함정도 저절로 설명됩니다.
yield return 은 만들다 말고 멈춘다
배열과 List 와 문자열은 안이 전혀 다른데 같은 foreach 로 돕니다. 무엇을 갖추면 돌 수 있는지 봅니다.
Equals 와 GetHashCode 는 반드시 같이 고친다
방금 넣은 값을 같은 키로 꺼냈는데 없다고 나옵니다. 해시가 먼저 자리를 정하기 때문입니다.
연산자도 메서드다
a + b 의 + 는 결국 메서드 하나입니다. 내가 만든 타입에도 그 메서드를 달 수 있습니다.
확장 메서드는 붙는 것이 아니라 붙어 보이는 것이다
string 을 고칠 수 없는데 string 에 메서드를 하나 늘리는 법. 그리고 그게 진짜 늘어난 게 아닌 이유.
인스펙터는 내 private 필드를 어떻게 아는가
감춘 필드가 화면에 나오고, 문자열로 적은 메서드 이름이 실행됩니다. 실행 중에 코드가 코드를 읽기 때문입니다.
const 는 컴파일할 때, readonly 는 실행할 때 정해진다
둘 다 못 바꾸게 막는데 막히는 시점이 다릅니다. 그 차이가 남의 프로젝트에서 사고를 냅니다.
문자열을 반복문 안에서 이으면 매번 새로 만든다
못 바꾼다는 성질의 대가는 반복 횟수만큼 붙습니다. 그런데 대부분의 자리에서는 신경 쓸 필요가 없습니다.
박싱은 값을 힙으로 보내는 일이다
object 자리에 int 를 넣으면 값이 상자에 담겨 힙으로 갑니다. 그 상자값이 얼마인지 봅니다.
struct 는 값을 담고 class 는 주소를 담는다
int 가 힙에 안 가는 이유, 그리고 힙에 안 가는 타입을 직접 만드는 법.
static 은 객체가 아니라 클래스에 붙는다
처음 쓴 코드가 static void Main 이었는데, 그 static 이 무엇인지는 아무도 설명하지 않았습니다.