프랙티컬 C#

관용구, 정석, 패턴으로 배우는 C# 프로그래밍 테크닉

대부분의 초보 프로그래머들은 ’C#의 기본적인 문법은 어느 정도 이해했지만 지금 알고 있는 문법을 어떻게 적용하고 프로그램을 어떻게 만들어야 할지 잘 모르겠다.’라는 고민을 가지고 있을 것입니다. 이 책은 C#을 이제 정석으로 공부하려고 하는 독자를 위한 책입니다.

C#의 문법을 이해한 것만으로는 프로그램을 작성할 수 없습니다. 지금 해결하려고 하는 문제의 순서를 생각하고 여기에 이용할 데이터의 구조를 생각한 후에 이를 C# 코드로 작성하는 기술이 필요합니다. .NET 프레임워크에 마련돼 있는 다양한 클래스를 활용하는 방법도 알아둬야 하고 C# 코드를 나중에 변경하기 쉽게 작성하기 위한 지식도 필요합니다.

이런 기술을 습득하는 지름길은 현장에서 이용되는 ‘관용구’, ‘정석’, ‘패턴’을 학습하는 것입니다. 이 패턴을 잘 기억하는 것이 고수가 되는 지름길인 것입니다. 이 책에서는 이해하기 어려웠던 객체지향에 관한 내용을 다시 확인하는 과정에서 출발합니다. 그리고 현장에서 사용되는 ‘관용구/정석’을 중심으로 해서 C#에 포함된 편리한 기능을 사용하는 방법, 데이터를 다루는 방법, 프레임워크를 이용하는 방법을 알기 쉽게 풀어서 설명함으로써 독자가 C# 프로그래밍에 익숙해질 수 있게 합니다. 또한 이 책에서 알게 된 문법을 어떻게 적용할지, 어떻게 프로그래밍할지, 왜 프로그램을 그렇게 작성해야 하는지에 관해서도 자세히 설명합니다.

이데이 히데유키 (出井 秀行)

일본 토치기현 출생. 동경이과대학 이공학부 정보과학과 졸업. FORTRAN, Pascal, BASIC, COBOL, C, C++, Delphi 등 많은 언어를 사용해오다가 2002년에 C#을 접하고 그 훌륭함에 매료된 후 현재까지 C#을 주로 사용하고 있다. 2004년부터 gushwell이라는 핸들명으로 온라인 활동을 시작했다. 메일 매거진이나 블로그를 통해 C# 기술에 관한 정보를 알리고 있다. 2005년부터 12년 연속으로 마이크로소프트 MVP 어워드를 수상했다. 취미는 독서, 사진, 농구이다.

김범준

일본 호세이대학 경영학부를 졸업했다. 대학 시절 취미로 프로그래밍을 시작한 것을 계기로 이 업계에 발을 들여놓게 됐으며, 한국과 일본에서 임베디드 시스템과 게임 관련 회사에서 개발 프로젝트를 진행했다. 번역서로는 《정석으로 배우는 딥러닝》 《러닝스쿨! 파이썬 교과서》 《유니티 UI 디자인 교과서》 《머신러닝 이론 입문》 《모던 C 언어 프로그래밍》 《따라 하면서 배우는 유니티 3D 입문》이 있으며, 저서로는 《만들면서 배우는 OS커널의 구조와 원리》 《뇌를 자극하는 하드웨어 입문》이 있다.

  • [01부] 준비 편
    •  
    • ▣ 01장: 객체지향 프로그래밍 기초
      • 1.1 클래스
        • 1.1.1 클래스를 정의한다
        • 1.1.2 클래스의 인스턴스를 생성한다
        • 1.1.3 객체를 이용한다
        • 1.1.4 인스턴스는 여러 개 만들 수 있다
      • 1.2 구조체
      • 1.3 값형과 참조형
        • 1.3.1 값형에 대해서
        • 1.3.2 참조형에 대해서
        • 1.3.3 왜 값형과 참조형이라는 두 가지 형이 필요할까?
      • 1.4 정적 멤버와 정적 클래스
        • 1.4.1 정적 속성과 정적 메서드
        • 1.4.2 정적 클래스
      • 1.5 네임스페이스
      • 1.6 상속
        • 1.6.1 상속이란?
        • 1.6.2 is a 관계
    •  
    • ▣ 02장: C#으로 프로그램을 만들어보자
      • 2.1 거리를 환산하는 프로그램
        • 2.1.1 첫 버전
        • 2.1.2 계산 로직을 메서드의 형태로 독립시킨다
        • 2.1.3 프로그램에 기능을 추가한다
        • 2.1.4 메서드의 기능을 단순하게 한다
        • 2.1.5 클래스로 분리한다
        • 2.1.6 클래스를 이용한다
        • 2.1.7 정적 메서드로 수정한다
        • 2.1.8 정적 클래스로 수정한다
        • 2.1.9 상수를 정의한다
        • 2.1.10 완성된 소스코드
      • 2.2 매출을 계산하는 프로그램
        • 2.2.1 Sale 클래스를 정의한다
        • 2.2.2 CSV 파일을 읽어 들인다
        • 2.2.3 점포별 매출을 구한다
        • 2.2.4 집계된 결과를 출력한다
        • 2.2.5 초판이 완성됐다
        • 2.2.6 메서드를 이동시킨다
        • 2.2.7 새 생성자를 추가한다
        • 2.2.8 클래스를 인터페이스로 바꾼다
        • 2.2.9 var라는 암시형을 활용한다
        • 2.2.10 완성된 소스코드
    •  
    • ▣ 03장: 람다식과 LINQ 기초
      • 3.1 람다식 이전
        • 3.1.1 메서드를 인수로 넘겨준다
        • 3.1.2 델리게이트를 사용한다
        • 3.1.3 익명 메서드를 이용한다
      • 3.2 람다식
        • 3.2.1 람다식이란?
        • 3.2.2 람다식을 사용한 예
      • 3.3 List 클래스와 람다식의 조합
        • 3.3.1 Exists 메서드
        • 3.3.2 Find 메서드
        • 3.3.3 FindIndex 메서드
        • 3.3.4 FindAll 메서드
        • 3.3.5 RemoveAll 메서드
        • 3.3.6 ForEach 메서드
        • 3.3.7 ConvertAll 메서드
      • 3.4 LINQ to Objects의 기초
        • 3.4.1 LINQ to Objects의 간단한 예
        • 3.4.2 쿼리 연산자
        • 3.4.3 시퀀스
        • 3.4.4 지연 실행
    •  
  • [02부] 기초 편
    •  
    • ▣ 04장: 기본 관용구
      • 4.1 초기화와 관련된 관용구
        • 4.1.1 변수의 초기화
        • 4.1.2 배열과 리스트 초기화
        • 4.1.3 Dictionary 초기화
        • 4.1.4 객체 초기화
      • 4.2 판정과 분기에 관한 관용구
        • 4.2.1 단순한 비교
        • 4.2.2 수치가 어떤 범위에 있는지를 조사한다
        • 4.2.3 else-if를 통한 다분기 처리
        • 4.2.4 체로 걸러 남은 것만을 처리한다
        • 4.2.5 bool 값을 판단한다
        • 4.2.6 bool 값을 반환한다
      • 4.3 반복에 관한 관용구
        • 4.3.1 지정한 횟수만큼 반복한다
        • 4.3.2 컬렉션에 있는 요소를 모두 꺼낸다
        • 4.3.3 List에 있는 모든 요소를 처리한다
        • 4.3.4 적어도 한 번은 반복하는 것
        • 4.3.5 루프 도중에 처리를 중단한다
      • 4.4 조건 연산자, null 합체 연산자를 사용한 관용구
        • 4.4.1 조건에 따라 대입할 값을 변경한다
        • 4.4.2 null 합체 연산자
        • 4.4.3 null 조건 연산자
      • 4.5 속성에 관한 관용구
        • 4.5.1 속성 초기화에 관련된 관용구
        • 4.5.2 읽기 전용 속성
        • 4.5.3 참조형인 읽기 전용 속성
      • 4.6 메서드에 관한 관용구
        • 4.6.1 가변 인수
        • 4.6.2 오버로드는 하지 않고 옵션 인수를 사용한다
      • 4.7 그 밖의 관용구
        • 4.7.1 1을 더할 때는 증감 연산자 ++를 사용한다
        • 4.7.2 파일 경로에는 축자 문자열 리터럴을 이용한다
        • 4.7.3 두 개의 요소를 바꾼다
        • 4.7.4 문자열을 숫자값으로 변환한다
        • 4.7.5 참조형을 형변환한다
        • 4.7.6 예외를 다시 던진다
        • 4.7.7 using을 사용해 리소스를 정리한다
        • 4.7.8 여러 개의 생성자를 정의한다
    •  
    • ▣ 05장: 문자열을 처리한다
      • 5.1 문자열을 비교한다
        • 5.1.1 문자열끼리 비교한다
        • 5.1.2 대/소문자 구분 없이 비교한다
        • 5.1.3 히라가나/카타카나 구분 없이 비교한다
        • 5.1.4 전각/반각 구별없이 비교한다
      • 5.2 문자열을 판정한다
        • 5.2.1 null 또는 빈 문자열을 판정한다
        • 5.2.2 지정한 부분 문자열로 시작되는지 조사한다
        • 5.2.3 지정한 부분 문자열이 포함돼 있는지 조사한다
        • 5.2.4 지정한 문자열이 포함돼 있는지 조사한다
        • 5.2.5 조건을 만족하는 문자가 포함돼 있는지 조사한다
        • 5.2.6 모든 문자가 조건을 만족하는지 조사한다
      • 5.3 문자열을 검색하고 추출한다
        • 5.3.1 부분 문자열을 검색하고 그 위치를 구한다
        • 5.3.2 문자열의 일부를 추출한다
      • 5.4 문자열을 변환한다
        • 5.4.1 문자열의 앞뒤에 있는 공백을 제거한다
        • 5.4.2 지정한 위치부터 임의 개수의 문자를 삭제한다
        • 5.4.3 문자열에 다른 문자열을 삽입한다
        • 5.4.4 문자열의 일부를 다른 문자열로 치환한다
        • 5.4.5 소문자를 대문자로 변환한다/대문자를 소문자로 변환한다
      • 5.5 문자열을 연결하고 분할한다
        • 5.5.1 두 개의 문자열을 연결한다
        • 5.5.2 문자열 끝에 다른 문자열을 추가한다
        • 5.5.3 지정한 구분 문자로 문자열 배열을 연결한다
        • 5.5.4 지정한 문자로 문자열을 분할한다
        • 5.5.5 StringBuilder를 사용해 문자열을 연결한다
      • 5.6 그 밖의 문자열 처리
        • 5.6.1 문자열에서 문자를 하나씩 꺼낸다
        • 5.6.2 문자 배열로 문자열을 생성한다
        • 5.6.3 숫자값을 문자열로 변환한다
        • 5.6.4 지정한 서식으로 문자열을 형성한다
    •  
    • ▣ 06장: 배열과 LiSt를 처리한다
      • 6.1 이번 장에서 공통으로 사용하는 코드
      • 6.2 요소를 설정한다
        • 6.2.1 배열 또는 List를 동일한 값으로 채운다
        • 6.2.2 배열 또는 List에 연속된 값을 설정한다
      • 6.3 컬렉션을 집계한다
        • 6.3.1 평균값을 구한다
        • 6.3.2 최솟값과 최댓값을 구한다
        • 6.3.3 조건에 일치하는 요소를 센다
      • 6.4 컬렉션을 판정한다
        • 6.4.1 조건에 일치하는 요소가 존재하는지 조사한다
        • 6.4.2 모든 요소가 조건을 만족하는지 조사한다
        • 6.4.3 두 컬렉션이 같은지 조사한다
      • 6.5 단일 요소를 구한다
        • 6.5.1 조건에 일치하는 첫/마지막 요소를 구한다.
        • 6.5.2 조건에 일치하는 첫/마지막 인덱스를 구한다
      • 6.6 여러 개의 요소를 구한다
        • 6.6.1 조건을 만족하는 n개의 요소를 구한다
        • 6.6.2 조건을 만족하는 동안에만 요소를 구한다
        • 6.6.3 조건을을 만족하는 동안에는 요소를 건너뛴다
      • 6.7 그 밖의 처리(변환, 정렬, 연결 등)
        • 6.7.1 컬렉션으로부터 다른 컬렉션을 생성한다
        • 6.7.2 중복을 제거한다
        • 6.7.3 컬렉션을 나열한다
        • 6.7.4 두 개의 컬렉션을 연결한다
    •  
    • ▣ 07장: 딕셔너리 다루기
      • 7.1 Dictionary의 기본적인 조작
        • 7.1.1 딕셔너리 초기화
        • 7.1.2 사용자 정의형 객체를 값으로 저장한다
        • 7.1.3 딕셔너리에 요소를 추가한다
        • 7.1.4 딕셔너리에서 요소를 꺼낸다
        • 7.1.5 딕셔너리에서 요소를 삭제한다
        • 7.1.6 딕셔너리에 있는 모든 요소를 꺼낸다
        • 7.1.7 딕셔너리에 있는 모든 키를 꺼낸다
      • 7.2 딕셔너리 응용
        • 7.2.1 딕셔너리로 변환한다
        • 7.2.2 딕셔너리로부터 다른 딕셔너리를 생성한다
        • 7.2.3 사용자 지정 클래스를 키로 이용한다
        • 7.2.4 키만을 저장한다
        • 7.2.5 키가 중복되는 것을 허용한다
      • 7.3 딕셔너리를 이용한 예제 프로그램
        • 7.3.1 Abbreviations 클래스
        • 7.3.2 Abbreviations를 이용한다
    •  
    • ▣ 08장: 날짜와 시간 처리
      • 8.1 DateTime 구조체
        • 8.1.1 DateTime 객체를 생성한다
        • 8.1.2 DateTime에 포함된 속성
        • 8.1.3 지정한 날짜의 요일을 구한다
        • 8.1.4 윤년을 판정한다
        • 8.1.5 날짜 형식의 문자열을 DateTime 객체로 변환한다
      • 8.2 날짜의 포맷
        • 8.2.1 날짜를 문자열로 변환한다
        • 8.2.2 날짜를 일본식으로 표시한다
        • 8.2.3 지정한 날짜의 연호를 구한다
        • 8.2.4 지정한 날짜에 해당하는 요일의 문자열을 구한다
      • 8.3 DateTime을 비교한다
        • 8.3.1 날짜와 시간을 비교한다
        • 8.3.2 날짜만 비교한다
      • 8.4 날짜를 계산한다(기초)
        • 8.4.1 지정한 시분초 이후의 시각을 구한다
        • 8.4.2 n일 후와 n일 전의 날짜를 구한다
        • 8.4.3 n년 후와 n개월 후를 구한다
        • 8.4.4 두 시각의 차를 구한다
        • 8.4.5 두 날짜의 차이를 구한다
        • 8.4.6 해당 월의 말일을 구한다
        • 8.4.7 1월 1일부터의 날짜 수를 구한다
      • 8.5 날짜를 계산한다(응용)
        • 8.5.1 다음 특정 요일을 구한다
        • 8.5.2 나이를 구한다
        • 8.5.3 지정한 날이 몇 주째에 있는지를 구한다
        • 8.5.4 지정한 달의 n번째의 X요일의 날짜를 구한다
    •  
  • [03부] 실전 편
    •  
    • ▣ 09장: 파일 처리
      • 9.1 텍스트 파일로 입력한다
        • 9.1.1 텍스트 파일을 한 행씩 읽어 들인다
        • 9.1.2 텍스트 파일을 한꺼번에 읽어 들인다
        • 9.1.3 텍스트 파일을 IEnumerable으로 취급한다
      • 9.2 텍스트 파일에 출력한다
        • 9.2.1 텍스트 파일에 한 행씩 문자열을 출력한다
        • 9.2.2 기존 텍스트 파일 끝에 행을 추가한다
        • 9.2.3 문자열 배열을 한번에 파일에 출력한다
        • 9.2.4 기존 텍스트 파일의 첫머리에 행을 삽입한다
      • 9.3 파일 처리
        • 9.3.1 파일이 존재하는지 여부를 조사한다
        • 9.3.2 파일을 삭제한다
        • 9.3.3 파일을 복사한다
        • 9.3.4 파일을 이동시킨다
        • 9.3.5 파일 이름을 수정한다
        • 9.3.6 파일을 수정한 시간과 만든 시간을 구하고 설정한다
        • 9.3.7 파일의 크기를 구한다
        • 9.3.8 File과 FileInfo 중 어느 쪽을 사용해야 할까?
      • 9.4 디렉터리 처리
        • 9.4.1 디렉터리가 존재하는지 여부를 조사한다
        • 9.4.2 디렉터리를 생성한다
        • 9.4.3 디렉터리를 삭제한다
        • 9.4.4 디렉터리를 이동시킨다
        • 9.4.5 디렉터리 이름을 수정한다
        • 9.4.6 지정한 폴더에 있는 디렉터리의 목록을 구한다
        • 9.4.7 지정한 폴더에 있는 디렉터리의 목록을 열거한다
        • 9.4.8 지정한 폴더에 있는 파일의 목록을 한번에 구한다
        • 9.4.9 지정한 폴더에 있는 파일의 목록을 열거한다
        • 9.4.10 디렉터리와 파일 목록을 함께 구한다
        • 9.4.11 디렉터리와 파일이 변경된 시각을 수정한다
      • 9.5 경로 이름을 처리한다
        • 9.5.1 경로 이름을 구성 요소로 분할한다
        • 9.5.2 상대 경로로부터 절대 경로를 구한다
        • 9.5.3 경로를 구성한다
      • 9.6 그 밖의 파일 처리
        • 9.6.1 임시 파일을 생성한다
        • 9.6.2 특수 폴더의 경로를 구한다
    •  
    • ▣ 10장: 정규 표현식을 활용한 고급 문자열 처리
      • 10.1 정규 표현식이란?
      • 10.2 문자열을 판정한다
        • 10.2.1 지정한 패턴에 일치하는 부분 문자열이 있는지 여부를 판정한다
        • 10.2.2 지정한 패턴의 문자열이 시작되는지 여부를 판정한다
        • 10.2.3 지정한 패턴으로 문자열이 끝나는지 여부를 판정한다
        • 10.2.4 지정한 패턴에 완전히 일치하는지 여부를 판정한다
      • 10.3 문자열 검색
        • 10.3.1 처음에 나오는 부분 문자열을 찾는다
        • 10.3.2 일치하는 문자열을 모두 찾는다
        • 10.3.3 Matches 메서드의 결과에 LINQ를 적용한다
        • 10.3.4 일치한 부분 문자열의 일부만을 꺼낸다
      • 10.4 문자열을 치환하고 분할한다
        • 10.4.1 Regex.Replace 메서드를 사용해 쉽게 치환한다
        • 10.4.2 그룹화 기능을 이용한 치환
        • 10.4.3 Regex.Split 메서드를 이용해 분할한다
      • 10.5 더욱 수준 높은 정규 표현식
        • 10.5.1 수량자
        • 10.5.2 최장 일치와 최단 일치
        • 10.5.3 역참조 구문
    •  
    • ▣ 11장: XML 파일 처리
      • 11.1 예제 XML 파일
      • 11.2 XML 파일 입력
        • 11.2.1 특정 요소를 구한다
        • 11.2.2 특정 요소를 형변환해서 구한다
        • 11.2.3 속성을 구한다
        • 11.2.4 조건을 지정해 XML 요소를 구한다
        • 11.2.5 XML 요소를 정렬한다
        • 11.2.6 중첩된 자식 요소를 구한다
        • 11.2.7 자손 요소를 구한다
        • 11.2.8 익명 클래스의 객체 형태로 요소를 구한다
        • 11.2.9 사용자 지정 클래스의 객체 형태로 요소를 구한다
      • 11.3 XML 객체를 생성한다
        • 11.3.1 문자열로부터 XDocument를 생성한다
        • 11.3.2 문자열로부터 XElement을 생성한다
        • 11.3.3 함수 생성 기능으로 XDocument 객체를 조합한다
        • 11.3.4 컬렉션으로부터 XDocument를 생성한다
      • 11.4 XML을 편집하고 저장한다
        • 11.4.1 요소를 추가한다
        • 11.4.2 요소를 삭제한다
        • 11.4.3 요소를 치환한다
        • 11.4.4 XML 파일에 저장한다
      • 11.5 XML에서 쌍 정보를 다룬다
        • 11.5.1 쌍 정보 목록을 XML로 변환한다
        • 11.5.2 쌍 정보를 속성의 형태로 저장한다
        • 11.5.3 쌍 정보를 읽어 들인다
        • 11.5.4 Dictionary 객체를 XML로 변환한다
        • 11.5.5 XML 파일로부터 Dictionary 객체를 생성한다
    •  
    • ▣ 12장: 직렬화와 역직렬화
      • 12.1 객체를 XML 데이터로 저장하고 복원한다
        • 12.1.1 객체의 내용을 XML 형식으로 저장한다
        • 12.1.2 직렬화한 XML 데이터를 복원한다
        • 12.1.3 컬렉션 객체를 직렬화/역직렬화한다
      • 12.2 응용 프로그램 간에 XML 데이터를 주고받는다
        • 12.2.1 XmlSerializer를 사용해 직렬화한다
        • 12.2.2 XmlSerializer를 사용해 역직렬화한다
        • 12.2.3 XmlIgnore 속성으로 직렬화의 대상에서 제외한다
        • 12.2.4 속성으로 요소 이름(태그 이름)을 기본값에서 수정한다
        • 12.2.5 XmlSerializer를 사용해 컬렉션을 직렬화한다
        • 12.2.6 XmlSerializer를 사용해 컬렉션을 역직렬화한다
      • 12.3 JSON 데이터를 직렬화하고 역직렬화한다
        • 12.3.1 JSON 데이터로 직렬화한다
        • 12.3.2 JSON 데이터를 역직렬화한다
        • 12.3.3 Dictionary를 JSON 데이터로 직렬화한다
        • 12.3.4 JSON 데이터를 Dictionary로 역직렬화한다
    •  
    • ▣ 13장: 엔터티 프레임워크로 데이터에 접근한다
      • 13.1 엔터티 프레임워크에 있는 Code First를 이용한다
      • 13.2 프로젝트를 생성한다
        • 13.2.1 새 프로젝트를 생성한다
        • 13.2.2 NuGet으로 엔터티 프레임워크를 설치한다
      • 13.3 엔터티 클래스(모델)를 작성한다
      • 13.4 DbContext 클래스를 생성한다
        • 13.4.1 BooksDbContext 클래스를 생성한다
        • 13.4.2 데이터베이스 접속 문자열을 확인한다
      • 13.5 데이터를 추가한다
        • 13.5.1 데이터를 추가한다
        • 13.5.2 작성된 DB를 확인한다
      • 13.6 데이터를 읽는다
      • 13.7 또 데이터를 추가한다
        • 13.7.1 Authors만 추가한다
        • 13.7.2 이미 등록된 Author를 사용해 서적을 추가한다
      • 13.8 데이터를 수정한다
      • 13.9 데이터를 삭제한다
      • 13.10 수준 높은 쿼리
      • 13.11 관련 엔터티를 한꺼번에 읽어 들인다
      • 13.12 데이터 주석과 자동 마이그레이션
        • 13.12.1 데이터 주석
        • 13.12.2 자동 마이그레이션
    •  
    • ▣ 14장: 그 밖의 프로그래밍의 정석
      • 14.1 프로세스를 시작한다
        • 14.1.1 프로그램을 시작한다
        • 14.1.2 프로세스가 끝나기를 기다린다
        • 14.1.3 ProcessStartInfo 클래스를 사용해 섬세하게 제어한다
      • 14.2 버전 정보를 구한다
        • 14.2.1 어셈블리 버전을 구한다
        • 14.2.2 파일의 버전을 구한다
        • 14.2.3 UWP 패키지 버전(제품 버전)을 구한다
      • 14.3 응용 프로그램의 구성 파일을 구한다
        • 14.3.1 appSettings 정보를 구한다
        • 14.3.2 응용 프로그램 설정 정보를 열거한다
        • 14.3.3 독자적인 형식의 응용 프로그램 설정 정보를 구한다
      • 14.4 Http 통신
        • 14.4.1 DownloadString 메서드로 웹 페이지를 가져온다
        • 14.4.2 DownloadFile 메서드로 파일을 내려받는다
        • 14.4.3 DownloadFileAsync 메서드로 비동기 처리한다
        • 14.4.4 OpenRead 메서드로 웹 페이지를 가져온다
        • 14.4.5 RSS 파일을 가져온다
        • 14.4.6 매개변수를 주고 정보를 얻는다
      • 14.5 ZIP 아카이브 파일을 처리한다
        • 14.5.1 아카이브에 있는 모든 파일을 추출한다
        • 14.5.2 아카이브에 저장돼 있는 파일의 목록을 구한다
        • 14.5.3 아카이브에서 임의의 파일을 추출한다
        • 14.5.4 지정한 디렉터리 안에 있는 파일을 아카이브로 만든다
      • 14.6 협정 세계시와 시간대
        • 14.6.1 현지 시각과 그에 대응되는 UTC를 구한다
        • 14.6.2 문자열을 DateTimeOffset으로 변환한다
        • 14.6.3 지정한 지역의 시간대를 구한다
        • 14.6.4 시간대 목록을 구한다
        • 14.6.5 지정한 지역의 현재 시각을 구한다
        • 14.6.6 한국 시간을 다른 지역의 시간으로 변환한다
        • 14.6.7 A 지역의 시각을 B 지역의 시각으로 변환한다
    •  
  • [04부] 고급 편
    •  
    • ▣ 15장: LINQ 사용
      • 15.1 이번 장에서 이용할 서적 데이터
      • 15.2 입력 소스가 한 개인 경우에 LINQ를 이용하는 법
        • 15.2.1 어떤 조건 안에서 최댓값을 구한다
        • 15.2.2 최솟값인 요소를 한 개만 구한다
        • 15.2.3 평균값 이상인 요소를 모두 구한다
        • 15.2.4 중복을 제거한다
        • 15.2.5 여러 개의 키로 나열한다
        • 15.2.6 여러 요소 가운데 어느 하나에 해당하는 객체를 구한다
        • 15.2.7 GroupBy 메서드로 그룹화한다
        • 15.2.8 ToLookup 메서드로 그룹화한다
      • 15.3 입력 소스가 여러 개 있을 때 LINQ를 사용하는 법
        • 15.3.1 두 개의 시퀀스를 결합한다
        • 15.3.2 두 개의 시퀀스를 그룹화해서 결합한다
    •  
    • ▣ 16장: 비동기/병렬 프로그래밍
      • 16.1 비동기 처리와 병렬 처리의 필요성
      • 16.2 async/await 이전의 비동기 프로그래밍
        • 16.2.1 스레드를 이용한 비동기 처리
        • 16.2.2 BackgroundWorker 클래스를 사용한 비동기 처리
        • 16.2.3 Task 클래스를 이용한 비동기 처리
      • 16.3 async/await를 이용한 비동기 프로그래밍
        • 16.3.1 이벤트 핸들러를 비동기로 만든다
        • 16.3.2 비동기 메서드를 정의한다
      • 16.4 HttpClient를 이용한 비동기 처리(async/await 응용 예)
        • 16.4.1 HttpClient를 사용한 간단한 예
        • 16.4.2 HttpClient를 응용한다
      • 16.5 UWP에서의 비동기 IO 처리
        • 16.5.1 파일 피커를 사용해 파일에 접근한다
        • 16.5.2 로컬 폴더에 텍스트 파일을 출력한다
        • 16.5.3 로컬 폴더에 있는 텍스트 파일을 읽어 들인다
        • 16.5.4 앱을 설치한 폴더에서 파일을 읽어 들인다
      • 16.6 병렬 처리 프로그래밍
        • 16.6.1 PLINQ로 병렬 처리한다
        • 16.6.2 Task 클래스를 이용한 병렬 처리
        • 16.6.3 HttpClient를 병렬 처리한다
    •  
    • ▣ 17장: 실전 객체지향 프로그래밍
      • 17.1 다형성 기초
        • 17.1.1 상속을 사용해 다형성을 구현한다
        • 17.1.2 인터페이스를 사용해 다형성을 구현한다
      • 17.2 템플릿 메서드 패턴
        • 17.2.1 라이브러리와 프레임워크
        • 17.2.2 텍스트 파일을 처리하는 프레임워크
        • 17.2.3 텍스트 파일을 처리하는 프레임워크를 구현한다
        • 17.2.4 프레임워크를 이용한다(응용 프로그램 작성)
        • 17.2.5 프로그램을 실행한다
      • 17.3 전략 패턴
        • 17.3.1 거리 환산 프로그램을 다시 생각해본다
        • 17.3.2 Converter에 공통되는 메서드와 속성을 정의한다
        • 17.3.3 Converter의 구상 클래스를 정의한다
        • 17.3.4 거리를 단위 변환하는 클래스를 정의한다
        • 17.3.5 객체 생성을 한 곳에서 관리한다
        • 17.3.6 프로그램을 완성한다
    •  
    • ▣ 18장: 스타일, 네이밍, 주석
      • 18.1 스타일에 관한 지침
        • 18.1.1 구조를 들여쓰기에 반영한다
        • 18.1.2 괄호를 사용해 정리한다
        • 18.1.3 공백을 일관성 있게 유지한다
        • 18.1.4 한 행에 모든 것을 넣지 않는다
      • 18.2 네이밍에 관한 지침
        • 18.2.1 파스칼 표기법과 낙타 표기법을 적절히 사용한다
        • 18.2.2 그것이 나타내는 것을 설명하는 이름을 지정한다
        • 18.2.3 정확한 철자를 사용한다
        • 18.2.4 로컬 변수의 생략형은 오해가 없는 범위 안에서 이용한다
        • 18.2.5 로컬 변수이면서 한 문자 변수는 용도를 정한다
        • 18.2.6 변수 이름/속성 이름은 명사가 좋다
        • 18.2.7 bool 형이라는 것을 알게 해주는 이름을 지정한다
        • 18.2.8 메서드 이름에는 동사를 지정한다
        • 18.2.9 바람직하지 않은 이름
      • 18.3 주석에 관한 지침
        • 18.3.1 당연히 알고 있는 것은 주석에 쓰지 않는다
        • 18.3.2 클래스나 메서드에 쓰는 주석은 개요를 쓴다
        • 18.3.3 코드를 읽어 알 수 없는 정보를 주석에 쓴다
        • 18.3.4 잘못된 코드에 주석을 쓰기보다는 코드를 수정한다
        • 18.3.5 주석은 필요한 최소한으로 제한한다
        • 18.3.6 주석 처리한 코드를 방치하지 않는다
        • 18.3.7 겉모습을 중시한 주석은 쓰지 않는다
    •  
    • ▣ 19장: 좋은 코드를 작성하기 위한 지침
      • 19.1 변수에 관한 지침
        • 19.1.1 변수의 스코프는 좁게 정한다
        • 19.1.2 매직 넘버를 사용하지 않는다
        • 19.1.3 한 변수를 계속 쓰면 안 된다
        • 19.1.4 한 변수에 여러 개의 값을 넣으면 안 된다
        • 19.1.5 변수 선언은 최대한 늦춘다
        • 19.1.6 변수의 개수는 적을수록 좋다
      • 19.2 메서드에 관한 지침
        • 19.2.1 중첩은 얕아야 한다
        • 19.2.2 return 문을 한 개로 정리하려고 애쓰면 안 된다
        • 19.2.3 실행 결과의 상태를 int 형으로 반환하면 안 된다
        • 19.2.4 메서드는 단일 기능으로 구현한다
        • 19.2.5 메서드를 짧게 구현한다
        • 19.2.6 만능 메서드를 만들지 않는다
        • 19.2.7 메서드 인수의 개수는 적을수록 좋다
        • 19.2.8 인수에 ref 키워드를 붙인 메서드는 정의하지 않는다
        • 19.2.9 인수에 out 키워드를 붙인 메서드는 최대한 정의하지 않는다
      • 19.3 클래스에 관한 지침
        • 19.3.1 필드는 비공개로 지정한다
        • 19.3.2 쓰기 전용 속성은 정의하지 않는다
        • 19.3.3 연속해서 참조할 때마다 다른 값을 반환하는 속성을 정의하면 안 된다
        • 19.3.4 비용이 드는 처리는 속성이 아닌 메서드로 정의한다
        • 19.3.5 객체가 저장하고 있는 다른 객체를 외부에 노출시키면 안 된다
        • 19.3.6 기저 클래스에 유틸리티 메서드를 포함시키면 안 된다
        • 19.3.7 속성을 인수 대신 사용하면 안 된다
        • 19.3.8 거대한 클래스를 작성하지 않는다
        • 19.3.9 new 수식자를 사용해 상속하는 부모 쪽 메서드를 대체하면 안 된다
      • 19.4 예외 처리에 관한 지침
        • 19.4.1 예외를 대충 해결하면 안 된다
        • 19.4.2 예외를 throw할 때 InnerException을 삭제해서는 안 된다
      • 19.5 그 밖의 바람직하지 않은 프로그래밍
        • 19.5.1 const를 오용한다
        • 19.5.2 중복된 코드
        • 19.5.3 복사/붙여넣기 프로그래밍
        • 19.5.4 Obsolete 속성이 붙은 클래스와 메서드를 계속 사용한다
        • 19.5.5 필요없는 코드를 그대로 남겨둔다
  • 45쪽, 4번째 줄

    foreach를 사용하면 반복 횟수를 지정할 수 있어서 코드를 작성할 때 실수하지 않게 됩니다.

    ==>

    foreach를 사용하면 반복 횟수를 지정하지 않아 코드를 작성할 때 실수하지 않게 됩니다.

  • 71쪽, 3번째 줄 코드

    var count=Count(numbers (int n)= n % 2==0)
    

    ==>

    var count = Count(numbers, (int n) => n % 2 == 0);
    
  • 104쪽, 본문 7번째 줄

    customers가 null일 경우에는

    ==>

    customers가 null이 아닌 경우에는

  • 108쪽, 첫 번째 예제 코드를 다음 내용으로 교체(화살표 설명을 서로 교체)

    class Program {
      static void Main(string[] args) {
        var obj = new MySample();
        obj.MyList.Add(6);      <--- List<int>를 자유롭게 이용할 수 있다
        obj.MyList.RemoveAt(0);
        obj.MyList[0] = 10;
        foreach (var n in obj.MyList) {
          Console.WriteLine(n);
        }
        // obj.MyList = new List<int>();   <--- 읽기 전용이므로 여기서 빌드 오류가 발생한다
        Console.ReadLine();
      }
    }
    
  • 115쪽, 페이지 상단 예제의 첫 번째 줄

    tif (Session["MyProduct"] is Product) {
    

    ==>

    if (Session["MyProduct"] is Product) {
    
  • 144쪽, 본문 1번째 줄

    이 예에서는 ‘제12조5항’

    ==>

    이 예에서는 ‘제12조 5항’

  • 157쪽, 예제 6.24를 다음과 같이 수정

    bool is1000OrLess = books.All(x => x.Price <= 1000);
    

    ==>

    bool is10000OrLess = books.All(x => x.Price <= 10000);
    
  • 218쪽, 예제 9.13의 3번째 줄

    using (var writer = new StreamWriter(filePath, append: true)) {
    

    ==>

    using (var writer = new StreamWriter(filePath, append:true)) {
    
  • 294쪽, 예제 12.2의 5번째 줄

    Author = 제임스 P. 호건",
    

    ==>

    Author = "제임스 P. 호건",
    
  • 296쪽, 예제 12.4의 3번째 줄

    Author = 제임스 P. 호건",
    

    ==>

    Author = "제임스 P. 호건",