길벗·이지톡

도서 IT 전문서 프로그래밍/오픈소스

C#의 내부 동작 방식을 이해하여 간결하고 생산성 높은 코드를 작성하자!

버전별 주요 기능을 이해한다

제네릭, null 가능 값 타입, 익명 메서드, 이터레이터, LINQ, 람다 표현식, 익명 타입, 객체 초기화자, 쿼리 표현식, 동적 타이핑, async/await, 비동기 메서드, 표현식 본문 멤버, 자동 구현 속성, 문자열 관련 기능, 튜플, switch 표현식, 패턴 매칭 등 다양한 기능을 현실적인 예제와 함께 배운다.

 

예제 200개로 생산성을 높이는 C# 작성법을 배운다

단순히 C# 공식문서에 있을 법한 사용법만 나열하는 것이 아니라, 200개가 넘는 예제 코드로 문제를 해결하는 다양한 해법을 구체적으로 제시한다. 그리고 이 과정을 지속적으로 거치면서 C# 코드를 간소화하고 생산성을 높이는 방법을 체득할 수 있다.

 

C# 내부 동작 방식을 이해하여 C# 전문가로 발돋움하자!

이 책은 C#의 내부 동작 방식을 존 스킷만의 경험과 매력적인 통찰로 담아냈다. 이를 통해 C#의 면면을 들여다보고 숨겨진 트릭을 발견하여 C#을 좀 더 C#답게 설계하고 프로그래밍 기술을 극대화하도록 돕는다.

목차

1C#에 대해서

 

1C# 개발자로 살아남기

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 요약

 

2C# 2-5

 

2C# 2

2.1 제네릭

__2.1.1 예제를 통한 소개: 제네릭 이전의 컬렉션

__2.1.2 시간을 절약하는 제네릭

__2.1.3 제네릭이 될 수 있는 것

__2.1.4 메서드의 타입 인수에 대한 타입 추론

__2.1.5 타입 제약 조건

__2.1.6 defaulttypeof 연산자

__2.1.7 제네릭 타입의 초기화와 상태

2.2 null 가능 값 타입

__2.2.1 목적: 정보가 없음을 나타내는 방법

__2.2.2 CLR과 프레임워크의 지원: Nullable<T> 구조체

__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 요약

 

3C# 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 요약

 

4C# 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<TResult>

__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.1 구체적인 예

__6.2.2 MoveNext( ) 메서드의 일반적인 구조

__6.2.3 대기 표현식에 대한 고찰

6.3 제어 흐름이 MoveNext( )에 미치는 영향

__6.3.1 대기 표현식 사이의 제어 흐름은 단순하다

__6.3.2 루프 내에 대기 표현식이 있는 경우

__6.3.3 try/finally 블록 내에 대기 표현식이 있는 경우

6.4 실행 컨텍스트와 흐름

6.5 사용자 정의 태스크 타입 재검토

6.6 요약

 

7C# 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 요약

 

3C# 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 요약

 

4C# 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<T>stackalloc

__13.6.3 IL 수준에서의 유사 참조 구조체

13.7 요약

 

14C# 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 요약

 

15C# 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 IndexRange

__15.4.1 IndexRange 타입 그리고 리터럴

__15.4.2 IndexRange 사용

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 참가를 독려하며

 

부록 버전별 언어 기능 

더보기접기

저자

ㆍ지은이 존 스킷

저자소개

구글의 소프트웨어 엔지니어로 런던 사무소에서 근무하고 있다. 담당 업무는 구글 클라우드 플랫폼용 .NET 클라이언트 라이브러

리를 개발하는 것인데, 이는 구글과 C#에 대한 열정을 동시에 쏟아부을 수 있는 일이다. C# 표준화를 담당하는 ECMA 기술 그룹

의 소장이며 .NET 파운데이션에서 구글을 대표하고 있다. 개발자를 위한 질의응답 사이트인 스택 오버플로(Stack Overflow)에

자주 참여하여 이를 통해 잘 알려져 있다. 그 외에도 콘퍼런스와 사용자 그룹, 블로그에서 연설하고 글을 쓰는 것을 즐긴다. 이 모

든 것의 공통점은 다른 개발자와 함께하는 방법이라는 것이며, 이를 통해 많은 것을 배운다.

ㆍ옮긴이 김명신

저자소개

한국 마이크로소프트에서 퍼블릭 클라우드를 잘 사용하는 방법을 전하고 있다. 이전에는 마이크로소프트 수석 에반젤리스트였

고, APAC 글로벌 핵심 개발자 지원팀 수석 엔지니어였으며 다년간 C++와 C# 분야의 마이크로소프트 MVP이기도 했다. 클라우

드, 분산 컴퓨팅 아키텍처, 대용량 네트워크 프로그래밍, 프로그래밍 방법론, 소프트웨어 공학 등 여러 분야에 두루 관심이 많고,

다양한 개발자 콘퍼런스에 단골 발표자로 참가하고 있다. 『Advance C Programming』, 『Unix System V』 등을 집필했고 『Effective C#』, 『제프리 리처의 Windows via C/C++』(이상 한빛미디어), 『제프리 리처의 CLR via C#』, 『마스터링 Microsoft Azure IaaS』, 『Microsoft Azure 에센셜』(이상 BJ퍼블릭) 등을 번역했다.

연관 프로그램

아래 프로그램은 길벗출판사가 제공하는 것이 아닙니다.
무료로 사용할 수 있는 정보를 안내해 드리니, 지원이 필요하면 해당 프로그렘 제작사로 문의해 주세요.