티스토리 뷰

2003년 .NET Framework 1.1로 시작해서 올해로 14년 정도 C#을 사용하여 개발해왔다. 물론 지난 기간 동안 C# 만을 사용해서 개발한 것은 아니다. 14년이면 짦은 시간은 아니지만, 아직도 C#에 대해 모르는 것들이 많다. 문법이나 SDK 에 관한 문제도 있지만, 특히 C#을 효율적으로 사용하는 방법이라든가 적절하면서도 정확하게 사용하는 방법 등이다. Framework에는 다양한 클래스와 메소드 그리고 옵션들이 존재하는데, 이런 옵션들을 정확하게 다 알고 사용하기란 쉽지 않은 일이다. 기억력이 좋지 않는 나로써는 이전에 익혔던 것들도 간혹 잊어버리는 경우가 허다한 지라 어려움이 많다. 그래서 "C# 코딩의 기술 기본편 : 똑똑하게 코딩하는 방법" 같은 제목을 가진 책들은 구매하고 싶은 유혹에 쉽게 빠진다. 이 책은 래머군, 천사양, 악마씨 3명이 코딩에 대한 대화 형식으로 구성되어 있다. 먼저 래머군이 특정 주제에 대해 자기가 작성한 코딩을 제시하고 천사양과 악마씨가 각각 작성한 코드를 제시하고 티격태격되며 서로의 코드를 설명한다. 거의 천사양 코드가 추천 코드, 악마씨 코드는 완성도가 떨어지거나 좋지 않은 코드로 설정된다. 전반적으로 책에서 서술하는 코딩 기법 자체가 입문자 수준이긴 한데, 이 내용들이 입문자들이 이해하기 쉽게 서술됐는냐로 따진다면 물음표다. 일단 문제 제기에 대한 해결책으로 나온 코드나 방법이 납득할만한 수준의 최적의 솔루션이 아니며, 왜 그렇게 코딩해야 하는가에 대한 의문점을 깔끔하게 해결해주지 못한다. C#을 처음 접하는 개발자들이 이 채을 보고 왜 이렇게 코딩해야하는지에 대한 정확한 이해없이 관습적으로 코딩하지 않을까 하는 걱정이 든다. 예를 들어 예전에 컬렉션을 IEnumerable 인터페이스로 캐스팅하여 MoveNext() 메소드로 값을 가져오는 개발자를 봤다. 그런데 왜 IEnumerable로 캐스팅해서 사용하냐고 물어보면, 다른 소스에서 봤는데요라는 답변이였다. IEnumerable은 Iterator 패턴 인터페이스이다. 따라서 IEnumerable이 구현된 컬렉션은 foreah를 사용하여 값을 가져오면 된다. 구지 IEnumerable로 가져올 필요가 없다. 또 다른 예로 String 형식의 개체에 ToString()를 습관적으로 붙이는 경우도 봤다. 예제 소스에서 ToString()을 쓰니까 그냥 사용한다.  String 형인데 다시 ToString() 메소드 호출은 비효율적일 뿐만 아니라, Primitive 타입이 아니기 때문이 널(null)을 항상 체크하여 한다. 따라서 이 경우처럼 ToString()을 호출하는 것은 NullReferenceException을 불필요하게 발생시킬수 있다는 것이다. 이런 실수를 의외로 많이 봤다. 그리고 또 다른 예로 XSLT를 설명하면서, 스펙이 맞지 않고 최신 구현체가 .NET에 없다는 설명은 좋다. 그래서 XSLT를 사용하지 말것을 권고하는 것도 좋다. 그러면, 다른 해결책은? 필요한 문서를 생성할 때 마다 빌더 클래스를 만들란 건지, 아니면 오픈소스나 상용 리포팅 도구를 사용하란 건지? 사용한다면 레퍼런스 제품은 뭐가 있는지 정도는 알려줘야 하지 않을까? 개인적으로 간단한 문서 변환의 경우 XSLT를 사용한다. 1.0 스펙으로도 왠만한 것들은 구현이 가능하기 때문에 어렵다거나 귀찮은 적은 없다. 내부용을 쓸건데 XSLT를 아예 쓰지 말란 것도 좀 우습다. yield 키워드를 사용하는 부분도 신중이 결정해야 하는 부분이다. yield 키워드가 지연 처리를 하기 때문에 메모리 관리 부분에서는 좋을 수 있다. 하지만 yield는 느리다. 그리고 yield 가장 적절한 용도는 데이터 무한 공급이 필요한 곳에 가장 적합한 키워드이다. 잘못 사용하면 지옥적인 성능을 맞볼것이다. 코딩에 대한 올바른 길을 제시하려면, 이 코드가 왜 다른 코드보다 나은지에 대한 좀더 깉은 통찰력과 이해력을 증진해야 하고 이를 응용해서 여러 유사 코드를 자유자재로 작성할 수 있도록 도와야 한다. 그런데 이 책은 그런 점에서 만족스럽지 못하다. 대화식으로 그런지 너무 쓸데없는 내용들이 많고 실제 건져야 할 내용이 상대적으로 적다. 항상 장점이 있으면 단점도 있는 법이고 이런 부분을 충분히 설명해야 하는데, 이 책은 그런 부분이 부족하다. 솔직히 예전에 조금 어렵지만, Effective C#이라는 책이 휠씬 좋았던 것 같다.  원서로는 계속 판올림을 하고 있지만, 번역서는 1판에서 나오지 않기 때문에 아쉽다. 총평하자면, 내용이 충분하지 않아 오용의 소지가 있고 해결책이 항상 최적도 아니며, 항상 솔루션이 있는 것도 아니라 입문자에게도 비추. 또한 내용이 깊이 있는 것도 아니라 중급 이상에게도 비추. 그냥 읽어보면 이런 내용이 있구나 정도로만 보면 딱일듯한 책이다.  

일반적인 C# 입문서와 학교에서는 알려주지 않았던 C# 프로그래밍 베스트 노하우이 책은 변수 선언을 어떻게 하는지, 배열이 무엇인지에 관해서는 설명하지 않는다. 바로 하나의 코드를 던져주며 이 코드에서 놓치고 있는 함정은 무엇인지, 예고된 버그의 온상은 어디인지, 무엇을 어떻게 수정하면 좋을지를 스토리와 함께 쉽고 재미있게 알려준다. C# 코딩의 기술 은 단순히 좋은 코드와 나쁜 코드를 비교하면서 고급 수준의 코딩 스킬을 알려주는 책은 아니다. 그보다는 개발자들이 실무 현장에서 맞닥뜨리는 수많은 문제들을 보다 똑똑하고 현명하게 해결할 수 있도록 발상을 전환하고 문제 해결의 포인트를 정확히 짚을 수 있는 정수를 알려주는 책이다.

1장. 언어 사양 문제
1.1 var 사용에 관한 고민
1.2 if와 switch에 관한 오해
1.3 for와 foreach에 관한 오해
1.4 while을 이용한 조건 판정
1.5 do는 유용하지만 잘 사용하지 않는다.
1.6 루프할 필요가 없는 루프
1.7 장황한 비동기 루프
1.8 해제되지 않는 참조
1.9 해제했다고 생각한 메모리
1.10 표현력이 과장된 형
1.11 표현력이 부족한 형
1.12 의미 없는 구조체 사용
1.13 포인터 사용
1.14 불필요한 형변환 남용
1.15 클래스 하나로 증후군
1.16 모두 public으로 증후군
1.17 모두 static으로 증후군
1.18 using문을 사용하지 않는 증후군
1.19 다중 언어 프로그래밍을 모른다
1.20 const를 사용할 수 있는데 일반 변수를 사용하는 문제
1.21 readonly를 사용할 수 있는데 일반 변수를 사용하는 문제
1.22 열거형을 사용하지 않고 상수를 정의한다
1.23 쓸데없이 깊은 클래스 계층
1.24 다른 네임스페이스에서 같은 이름 남용
1.25 인수가 너무 많을 때
1.26 virtual 남용
1.27 코드에 바로 패스워드를 적는다
1.28 예외 처리를 하지 않는데 catch한다
1.29 catch해서 아무것도 하지 않고 throw하기
1.30 의미 없이 반복되는 상속
1.31 위임해야 할 상황에 상속한다
1.32 이름이 너무 짧아서 생기는 문제
1.33 이름이 너무 길어서 생기는 문제
1.34 기호로 된 이름 때문에 생기는 문제

2장. 라이브러리 문제
2.1 구세대 컬렉션 사용
2.2 컬렉션 반환
2.3 윈폼에 대한 고집
2.4 윈폼 API를 직접 호출한다
2.5 오래된 기술 XML DOM
2.6 오래된 기술 XSLT
2.7 개별 형식 바이너리의 시리얼라이즈
2.8 지나친 예외 의존
2.9 XElement를 Nullable〈T〉로 변환할 수 있을 때
2.10 MVC에서 View에 로직을 작성하는 문제
2.11 루프와 로직이 섞여 있다
2.12 필요 없는 리소스 사용
2.13 자바여 편히 잠들라

3장. 개발 환경 문제
3.1 GAC에 얽힌 오해
3.2 Ngen 의존 증후군
3.3 런타임 버전이 너무 최신일 때
3.4 런타임 버전이 너무 오래됐을 때

4장. 알고리즘 문제
4.1 지나친 재귀 사랑
4.2 불변이 아닌 클래스
4.3 흩어진 정보
4.4 쿼리가 너무 많을 때
4.5 장황한 판정
4.6 고유성이 확보됐는데 판정한다
4.7 고유성이 확보되지 않았는데 판정하지 않는다
4.8 영원히 실행되지 않는 코드
4.9 비정상 종료 시 치명적인 처리를 중단하지 않는 코드
4.10 무횻값을 자주 사용하는 데이터 설계

5장. 비주얼 스튜디오 문제
5.1 편리한 확장 기능을 사용하지 않는 문제
5.2 편리한 확장 기능을 과하게 사용하는 문제
5.3 F1을 사용하지 않는 문제
5.4 F1에 의존하는 문제
5.5 NuGet을 사용하지 않는 문제
5.6 NuGet을 사용할 수 없는 문제
5.7 버전이 적합한 템플릿을 선택할 수 없는 문제
5.8 콘솔 어플리케이션부터 만드는 문제