C#을 다루는 기술
C#을 C#답게 사용하자!
200개의 예제로 실습하며 배우는 간결하고 효과적인 C# 작성법!
『C#을 다루는 기술』의 목표는 여러분이 C#을 최대한 편안하게 사용하도록 하는 것이다. C#의 주요 기능을 다루는 것은 물론이고, 그 내부 동작 방식을 C# 전문가인 저자만의 경험과 매력적인 통찰로 담아내 C#을 C#답게 사용하도록 돕는다. 또한, 200개가 넘는 현실적인 예제를 통해 문제를 해결하고 생산성 높은 코드를 작성하는 방법을 알려준다.
«C#을 다루는 기술»은 11~13장을 공개합니다.
목차
- 제 1 부 C#에 대해서
- 1장 C# 개발자로 살아남기
- 1.1 진화하는 언어
- 1.1.1 어떤 규모의 응용프로그램에도 유용한 타입 시스템
- 1.1.2 더욱 간결한 코드 작성
- 1.1.3 LINQ를 이용한 단순한 데이터 사용
- 1.1.4 비동기
- 1.1.5 효율과 복잡성 사이의 균형
- 1.1.6 쾌속 진화: 부 버전 도입
- 1.2 진화하는 플랫폼
- 1.3 진화하는 커뮤니티
- 1.4 진화하는 책
- 1.4.1 이 책이 다루는 범위
- 1.4.2 Noda Time을 이용하는 예제
- 1.4.3 용어 선택
- 1.5 요약
- 제 2 부 C# 2-5
- 2장 C# 2
- 2.1 제네릭
- 2.1.1 예제를 통한 소개: 제네릭 이전의 컬렉션
- 2.1.2 시간을 절약하는 제네릭
- 2.1.3 제네릭이 될 수 있는 것
- 2.1.4 메서드의 타입 인수에 대한 타입 추론
- 2.1.5 타입 제약 조건
- 2.1.6 default와 typeof 연산자
- 2.1.7 제네릭 타입의 초기화와 상태
- 2.2 null 가능 값 타입
- 2.2.1 목적: 정보가 없음을 나타내는 방법
- 2.2.2 CLR과 프레임워크의 지원: Nullable
구조체 - 2.2.3 언어 지원
- 2.3 델리게이트 작성 단순화
- 2.3.1 메서드 그룹 변환
- 2.3.2 익명 메서드
- 2.3.3 델리게이트의 호환성
- 2.4 이터레이터
- 2.4.1 이터레이터 소개
- 2.4.2 지연 수행
- 2.4.3 yield 문의 평가
- 2.4.4 지연 수행의 중요성
- 2.4.5 finally 블록의 평가
- 2.4.6 finally 처리의 중요성
- 2.4.7 구현 방식에 대한 밑그림
- 2.5 부가 기능
- 2.5.1 partial 타입
- 2.5.2 정적 클래스
- 2.5.3 속성 접근자에 대해 별도의 접근 한정자 지정
- 2.5.4 네임스페이스 별칭
- 2.5.5 pragma 지시자
- 2.5.6 고정 길이 버퍼
- 2.5.7 InternalsVisibleTo
- 2.6 요약
- 3장 C# 3: LINQ 그리고 함께 제공되는 모든 것
- 3.1 자동 구현 속성
- 3.2 암시적 타이핑
- 3.2.1 타이핑 관련 용어
- 3.2.2 지역 변수에 대한 암시적 타이핑(var)
- 3.2.3 배열에 대한 암시적 타입 지정
- 3.3 객체 초기화 구문과 컬렉션 초기화 구문
- 3.3.1 객체 초기화 구문과 컬렉션 초기화 구문 소개
- 3.3.2 객체 초기화 구문
- 3.3.3 컬렉션 초기화 구문
- 3.3.4 단일 표현식으로 초기화를 수행하는 방식의 이점
- 3.4 익명 타입
- 3.4.1 문법과 기본적인 동작 방식
- 3.4.2 컴파일러가 생성한 타입
- 3.4.3 한계
- 3.5 람다 표현식
- 3.5.1 람다 표현식 문법
- 3.5.2 변수 캡처
- 3.5.3 표현식 트리
- 3.6 확장 메서드
- 3.6.1 확장 메서드의 선언
- 3.6.2 확장 메서드의 수행
- 3.6.3 연쇄적 메서드 호출
- 3.7 쿼리 표현식
- 3.7.1 쿼리 표현식은 C#에서 C#으로의 변환
- 3.7.2 범위 변수와 투명 구분자
- 3.7.3 LINQ에 어떤 구문을 사용할지 언제 판단할 것인가?
- 3.8 최종 결과물: LINQ
- 3.9 요약
- 4장 C# 4: 상호 운용성의 개선
- 4.1 동적 타이핑
- 4.1.1 동적 타이핑 소개
- 4.1.2 리플렉션을 넘어선 동적 타이핑의 동작 방식
- 4.1.3 내부 동작에 대한 개요
- 4.1.4 동적 타이핑의 한계와 놀라운 점
- 4.1.5 동적 타입 사용 가이드
- 4.2 선택적 매개변수와 명명된 인수
- 4.2.1 기본값을 가진 매개변수와 이름을 가진 인수
- 4.2.2 메서드 호출의 의미 규정
- 4.2.3 버전 관리에 미치는 영향
- 4.3 COM 상호 운용성의 개선
- 4.3.1 Primary Interop Assembly 링크
- 4.3.2 COM에서 선택적 매개변수 활용
- 4.3.3 명명된 인덱서
- 4.4 제네릭 변성
- 4.4.1 변성에 대한 간단한 사용 예
- 4.4.2 인터페이스와 델리게이트 선언 시 변성을 지정하는 문법
- 4.4.3 변성의 제약 사항
- 4.4.4 제네릭 변성에 대한 실용적 사례
- 4.5 요약
- 5장 비동기 코드 작성
- 5.1 비동기 함수 소개
- 5.1.1 비동기와의 첫 만남
- 5.1.2 첫 번째 예제 쪼개기
- 5.2 비동기에 대해
- 5.2.1 비동기 수행의 기본
- 5.2.2 동기화 컨텍스트
- 5.2.3 비동기 메서드 모델링
- 5.3 비동기 메서드 선언
- 5.3.1 비동기 메서드의 반환 타입
- 5.3.2 비동기 메서드의 매개변수
- 5.4 await 표현식
- 5.4.1 대기 가능 패턴
- 5.4.2 대기 표현식의 제약 사항
- 5.5 반환값을 둘러싸고 있는 부분
- 5.6 비동기 메서드의 흐름
- 5.6.1 무엇을 언제까지 대기하는가?
- 5.6.2 대기 표현식의 평가
- 5.6.3 대기 가능 패턴 멤버의 이용
- 5.6.4 예외 뜯어보기
- 5.6.5 메서드 완료
- 5.7 비동기 익명 함수
- 5.8 C# 7에 도입된 사용자 정의 태스크 타입
- 5.8.1 99.9%의 사용 예: ValueTask
- 5.8.2 나머지 0.1%의 사용 예: 사용자 정의 태스크 타입 작성
- 5.9 C# 7.1에서 지원하는 비동기 Main 메서드
- 5.10 활용 팁
- 5.10.1 ConfigureAwait로 컨텍스트를 저장하는 것을 피하라
- 5.10.2 여러 작업이 독립적으로 수행될 수 있도록 작성하고 이를 병렬적으로 수행하라
- 5.10.3 동기 코드와 비동기 코드를 섞어 쓰지 마라
- 5.10.4 취소가 가능하도록 코드를 작성하라
- 5.10.5 비동기성을 테스트하라
- 5.11 요약
- 6장 비동기 구현
- 6.1 컴파일러가 생성한 코드의 구조
- 6.1.1 스텁 메서드: 사전 준비와 첫걸음 떼기
- 6.1.2 상태 머신의 구조
- 6.1.3 MoveNext( ) 메서드(고수준)
- 6.1.4 SetStateMachine 메서드와 상태 머신 박싱의 조화
- 6.2 MoveNext( )의 간단한 구현
- 6.2.3 대기 표현식에 대한 고찰
- 6.2.1 구체적인 예
- 6.2.2 MoveNext( ) 메서드의 일반적인 구조
- 6.3 제어 흐름이 MoveNext( )에 미치는 영향
- 6.3.1 대기 표현식 사이의 제어 흐름은 단순하다
- 6.3.2 루프 내에 대기 표현식이 있는 경우
- 6.3.3 try/finally 블록 내에 대기 표현식이 있는 경우
- 6.4 실행 컨텍스트와 흐름
- 6.5 사용자 정의 태스크 타입 재검토
- 6.6 요약
- 7장 C#5의 보너스 기능
- 7.1 foreach 루프 내에서 변수 캡처
- 7.2 호출자 정보 특성
- 7.2.1 기본적인 동작
- 7.2.2 로깅
- 7.2.3 INotifyPropertyChanged 구현 단순화
- 7.2.4 호출자 정보 특성의 지엽적 특이성
- 7.2.5 예전 버전의 .NET에서 호출자 정보 특성을 사용하는 방법
- 7.3 요약
- 제 3 부 C# 6
- 8장 매우 세련된 속성과 표현식 본문 멤버
- 8.1 속성의 간단한 역사
- 8.2 업그레이드된 자동 구현 속성 기능
- 8.2.1 읽기 전용 자동 구현 속성
- 8.2.2 자동 구현 속성 초기화
- 8.2.3 구조체 내의 자동 구현 속성
- 8.3 표현식 본문 멤버
- 8.3.1 계산이 필요한 읽기 전용 속성을 더 간단히 구현하는 방법
- 8.3.2 표현식 본문 메서드, 표현식 본문 인덱서, 표현식 본문 연산자
- 8.3.3 C# 6의 표현식 본문 멤버가 가지는 제약 사항
- 8.3.4 표현식 본문 멤버 사용 지침
- 8.4 요약
- 9장 문자열 관련 기능
- 9.1 .NET에서 문자열 포매팅을 수행하는 방법 요약
- 9.1.1 단순 문자열 포매팅
- 9.1.2 포맷 문자열을 이용하여 사용자 정의 포매팅 수행하기
- 9.1.3 현지화
- 9.2 보간 문자열 리터럴 소개
- 9.2.1 간단한 보간
- 9.2.2 보간 문자열 리터럴 내에서의 포맷 문자열
- 9.2.3 보간 축자 문자열 리터럴
- 9.2.4 컴파일러가 보간 문자열 리터럴을 다루는 방법(첫 번째)
- 9.3 FormattableString을 사용한 현지화
- 9.3.1 컴파일러가 보간 문자열 리터럴을 다루는 방법(두 번째)
- 9.3.2 컬처를 지정하여 FormattableString 포매팅하기
- 9.3.3 FormattableString의 다른 사용 예
- 9.3.4 이전 버전의 .NET에서 FormattableString을 사용하려면
- 9.4 활용법, 사용 지침, 한계
- 9.4.1 개발자와 컴퓨터, 하지만 최종 사용자는 아닌…
- 9.4.2 보간 문자열 리터럴의 엄격한 제약
- 9.4.3 할 수 있지만 해서는 안 될 때
- 9.5 nameof로 식별자에 접근
- 9.5.1 nameof의 첫 번째 사용 예
- 9.5.2 nameof의 일반적인 사용 예
- 9.5.3 nameof를 사용할 때 주의해야 할 트릭과 함정
- 9.6 요약
- 10장 간결한 코드 작성을 위한 다양한 기능
- 10.1 using static 지시자
- 10.1.1 정적 멤버 임포트
- 10.1.2 확장 메서드와 using static
- 10.2 객체 초기화자와 컬렉션 초기화자의 개선
- 10.2.1 객체 초기화자 내에서의 인덱서
- 10.2.2 컬렉션 초기화자 내에서 확장 메서드 사용
- 10.2.3 테스트 코드와 제품 코드
- 10.3 null 조건 연산자
- 10.3.1 간단하고 안전한 속성 역참조
- 10.3.2 null 조건 연산자에 대한 세부 사항
- 10.3.3 불 비교 처리
- 10.3.4 인덱서와 null 조건 연산자
- 10.3.5 null 조건 연산자를 이용하여 작업을 효율적으로 수행하는 방법
- 10.3.6 null 조건 연산자의 한계
- 10.4 예외 필터
- 10.4.1 예외 필터의 문법과 의미
- 10.4.2 작업 재시도
- 10.4.3 부수적으로 로깅 수행
- 10.4.4 개별적이고 구체적인 예외 필터 구성
- 10.4.5 단순히 throw만 쓰는 것은 어떤가?
- 10.5 요약
- 제 4 부 C# 7 그리고 그 이후
- 11장 튜플을 이용한 구성
- 11.1 튜플 소개
- 11.2 튜플 리터럴과 튜플 타입
- 11.2.1 문법
- 11.2.2 튜플 리터럴에서 추론된 요소 이름(C# 7.1)
- 11.2.3 여러 변수를 담을 수 있는 가방처럼 튜플 활용
- 11.3 튜플 타입과 변환
- 11.3.1 튜플 리터럴의 타입
- 11.3.2 튜플 리터럴을 튜플 타입으로 변환
- 11.3.3 튜플 타입 간 변환
- 11.3.4 튜플 변환의 사용
- 11.3.5 상속 시 튜플의 요소 이름 확인
- 11.3.6 같음 연산자와 같지 않음 연산자(C# 7.3)
- 11.4 CLR 수준에서의 튜플
- 11.4.1 System.ValueTuple<…> 소개
- 11.4.2 튜플 요소 이름 처리
- 11.4.3 튜플 변환 구현
- 11.4.4 튜플의 문자열 표현
- 11.4.5 일반적인 동일성 비교와 순차성 비교
- 11.4.6 구조적 동일성과 순차성 비교
- 11.4.7 웜플 튜플과 거대한 튜플
- 11.4.8 제네릭이 아닌 ValueTuple 구조체
- 11.4.9 확장 메서드
- 11.5 튜플의 대체제
- 11.5.1 System.Tuple<…>
- 11.5.2 익명 타입
- 11.5.3 명명된 타입
- 11.6 용도 및 권고 사항
- 11.6.1 비공개 API와 쉽게 변경되는 코드에서 사용
- 11.6.2 지역 변수
- 11.6.3 필드
- 11.6.4 튜플과 동적 타이핑은 잘 어울리지 않는다
- 11.7 요약
- 12장 분해와 패턴 매칭
- 12.1 튜플 분해
- 12.1.1 새로운 변수로 분해
- 12.1.2 분해 시 기존 변수나 속성에 값을 할당
- 12.1.3 튜플 리터럴의 분해에 대한 세부 사항
- 12.2 튜플이 아닌 타입에 대한 분해
- 12.2.1 인스턴스 분해 메서드
- 12.2.2 확장 분해 메서드와 오버로딩
- 12.2.3 컴파일러가 Deconstruct 호출을 처리하는 방법
- 12.3 패턴 매칭 소개
- 12.4 C# 7.0에서 사용할 수 있는 패턴
- 12.4.1 상수 패턴
- 12.4.2 타입 패턴
- 12.4.3 var 패턴
- 12.5 is 연산자와 함께 패턴 사용
- 12.6 switch 문에서 패턴 사용
- 12.6.1 가드 절
- 12.6.2 case 레이블에서 생성한 패턴 변수의 사용 범위
- 12.6.3 패턴을 사용하는 switch 문의 평가 순서
- 12.7 활용 시 고려 사항
- 12.7.1 분해를 사용해야 하는 경우
- 12.7.2 패턴 매칭을 사용해야 하는 경우
- 12.8 요약
- 13장 참조 전달을 통한 효율 개선
- 13.1 요점 재확인: ref에 대해서 무엇을 알고 있는가?
- 13.2 참조 지역 변수와 참조 반환
- 13.2.1 참조 지역 변수
- 13.2.2 참조 반환
- 13.2.3 조건 ?: 연산자와 참조 변수(C# 7.2)
- 13.2.4 읽기 전용 참조(C# 7.2)
- 13.3 in 매개변수(C# 7.2)
- 13.3.1 호환성을 위한 고려 사항
- 13.3.2 in 매개변수의 놀라운 변경 가능성: 외부에서의 변경
- 13.3.3 in 매개변수의 오버로딩
- 13.3.4 in 매개변수의 사용 지침
- 13.4 구조체를 읽기 전용으로 선언(C# 7.2)
- 13.4.1 배경: 읽기 전용 변수를 사용한 암시적 복사
- 13.4.2 구조체에 readonly 한정자 사용
- 13.4.3 XML 직렬화는 암시적으로 읽고 쓰는 작업
- 13.5 참조 매개변수나 in 매개변수를 취하는 확장 메서드
- 13.5.1 복사를 피하기 위해 확장 메서드에서 참조 매개변수나 in 매개변수를 사용하는 방법
- 13.5.2 확장 메서드에서 ref를 사용할 때의 제한 사항
- 13.6 유사 참조 구조체(C# 7.2)
- 13.6.1 유사 참조 구조체의 규칙
- 13.6.2 Span
와 stackalloc - 13.6.3 IL 수준에서의 유사 참조 구조체
- 13.7 요약
- 14장 C# 7을 이용한 간결한 코드 작성
- 14.1 지역 메서드
- 14.1.1 지역 메서드 내에서의 변수 사용
- 14.1.2 지역 메서드의 구현
- 14.1.3 사용 지침
- 14.2 out 변수
- 14.2.1 out 매개변수 사용 시 변수 선언을 인라인화
- 14.2.2 C# 7.3부터 out 변수와 패턴 변수에 대한 제약이 사라진 부분
- 14.3 숫자 리터럴 개선
- 14.3.1 이진 정수 리터럴
- 14.3.2 밑줄 구분자
- 14.4 throw 표현식
- 14.5 default 리터럴(C# 7.1)
- 14.6 명명된 인수의 사용 위치 제약 완화(C# 7.2)
- 14.7 private protected 접근 한정자(C# 7.2)
- 14.8 C# 7.3의 사소한 개선 사항
- 14.8.1 제네릭 타입 제약 조건
- 14.8.2 오버로드 해석의 개선
- 14.8.3 자동 구현 속성을 지원하기 위한 필드에 대한 특성
- 14.9 요약
- 15장 C# 8 그리고 그 이후
- 15.1 null 가능 참조 타입
- 15.1.1 null 가능 참조 타입은 어떤 문제를 해결하는가?
- 15.1.2 참조 타입 사용 시 의미 변경
- 15.1.3 null 가능 참조 타입
- 15.1.4 컴파일 타임과 런타임 시 null 가능 참조 타입
- 15.1.5 damnit 연산자, bang 연산자, null 허용 연산자
- 15.1.6 null 가능 참조 타입을 사용하도록 수정한 경험
- 15.2 switch 표현식
- 15.3 재귀 패턴 매칭
- 15.3.1 패턴 내에서 속성 매칭
- 15.3.2 분해 패턴
- 15.3.3 패턴에서 타입 생략
- 15.4 Index와 Range
- 15.4.1 Index와 Range 타입 그리고 리터럴
- 15.4.2 Index와 Range 사용
- 15.5 더 많은 비동기 기능 제공
- 15.5.1 await를 이용한 비동기 리소스 제거
- 15.5.2 foreach await를 이용한 비동기 순회
- 15.5.3 비동기 이터레이터
- 15.6 그 외의 기능들
- 15.6.1 기본 인터페이스 메서드
- 15.7 C# 9.0에 대하여
- 15.7.1 init 전용 세터
- 15.7.2 레코드
- 15.7.3 최상위 구문
- 15.7.4 개선된 패턴 매칭
- 15.7.5 대상-타입 고려 new 표현식
- 15.8 참가를 독려하며
- 부록 버전별 언어 기능