8장 - c# 3.0 - 2

2015. 1. 10. 12:39IT Books/시작하세요 C# 프로그래밍

확장 메서드

기존 클래스를 확장하면 방법.
상속이 많이 쓰이지만 
sealed로 봉인된 클래스이거나
클래스를 상속받아 확장하면 기존 소스를 상속받은 클래스는 새로운 이름으로 바뀌어야 한다.

이런 방식이 싫다면 확장 메서드를 쓰면 된다.
기존 클래스의 내부 구조를 전혀 바꾸지 않고 새 인스턴스 메서드를 추가할 수 있다.


이런 식으로 마치 진짜 string 클래스에 정의되어 있는 것처럼 사용이 가능하다.
하지만 실제로는 컴파일러는 위 코드를 ExtensionMethodSample.GetWordCount(str) 로 변경하는 것 뿐이다.

따라서 클래스를 상속받은 것처럼 부모 클래스의 protected 멤버 호출도 당연히 불가하고
override 같은 것도 안된다.


람다 식 (Lambda Expression)

람다 대수의 형식을 C#에서 구현한 문법.
위키피디아 참조[각주:1]

C#에서의 람다 식은 다음과 같이 구별

1. 코드로서의 람다
 - 익명 메서드의 간편 표기 용도로 사용

2. 데이터로서의 람다

 - 람다 식 자체가 데이터가 되어 구문 분석의 대상이 됨. 이 람다 식은 별도로 컴파일이 가능하며 메서드로도 호출 가능




위쪽 thread의 delegate를 아래쪽 람다 식에서는 생략했고

인자의 타입도 표기하지 않았다.


이런 람다 식이 사용된 코드는 컴파일러에서는 익명 메서드와 완전히 동일하게 확장해서 컴파일한다.


좀더 약식으로는 return문도 생략가능하다.



 
이렇게 편하게 사용가능하다.
다만 이런 약식 표현의 람다 식은 세미콜론을 써서 여러 줄의 코드를 쓸 수 없는 제약이 있다.


------------------------------------------------------------------------

일회성 코드를 간단히 표현할 때 람다 식을 많이 쓰게 되는데 delegate를 일일이 정해야 한다는 것은
큰 불편함이 아닐 수 없다.

때문에 ms는 자주 사용되는 delegate의 형식을 미리 정해 놓았다.

public delegate void Action<T>(T obj);
-> 반환값이 없는 델리게이트. T형식 매개변수는 입력될 인자 1개의 타입 지정

public delegate TResult Func<TResult>();
-> 반환값이 있는 델리게이트. TResult 형식 매개변수는 반환 타입을 지정


위 코드의 Action, Func는 인자의 개수가 정해져 있지만 MS에서 최대 16개까지 미리 타입을 지정해 놨으니

지정된 것을 사용하면 된다.


------------------------------------------------------------------------


Collection and Lambda Expression


컬렉션의 모든 요소를 열람하면서 수행할 작업이 있을 때 for, foreach를 사용했다.


Array. List<T> 컬렉션에 있는 ForEach 메서드를 써보자.




위 3가지 모두 동일한 결과를 보여준다.


일일이 루프를 돌리지 않고 위와 같이 람다 식을 인자로 받아 결과를 반환하는 특수한 메서드들도 있다.


람다 식을 이용한 지연 평가

Enumerable 타입에는 Where 확장메서드가 정의되어 있다.

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);


FindAll 처럼 Where도 같은 동작을 수행한다.

다만 Where는 IEnumerable<T>로 열거형을 반환한다.


 
위 코드처럼 엄밀하게 말해 Where를 사용한 구현은 WhereFunc와 비슷하다.

즉.
FindAll의 경우 메서드 실행이 완료되는 순간 람다 식이 컬렉션의 모든 요소를 대상으로 실행되어 조건을 만족하는 목록을 반환하지만,

Where의 경우 메서드 실행시에는 어떤 코드도 실행되지 않는다.
이후 열거자를 통해 요소 순회를 했을때 비로소 람다 식이 하나씩 실행된다.

이를 바로 지연된 평가 (Lazy Evalution)라 하고 IEnumerable<T>를 반환하는 모든 메서드가 이런 방식으로 동작한다.
지연된 평가의 장점은 역시 실제로 데이터가 필요한 순간에만 CPU 자원을 사용한다는 점이다.



단순 형변환 뿐만 아니라 

객체 반환

익명 타입까지도 구성하여 반환이 가능하다.


데이터로서의 람다 식


람다 식을 코드가 아닌, 그 자체의 '식을 표현한 데이터'로 사용가능하다.

이를 식 트리 (Expression Tree)라고 한다.


식 트리로 담긴 람다 식은 익명 메서드가 아니기 때문에 System.Linq.Expressions.Expression 타입의 인스턴스가 된다.



위 코드처럼 데이터로 담겨 있는 람다 식은 컴파일도 가능.



  1. http://ko.wikipedia.org/wiki/%EB%9E%8C%EB%8B%A4_%EB%8C%80%EC%88%98 [본문으로]

'IT Books > 시작하세요 C# 프로그래밍' 카테고리의 다른 글

9장 - C# 4.0  (0) 2015.01.16
8장 - C# 3.0 - 3  (0) 2015.01.12
8장 - C# 3.0 - 1  (0) 2015.01.06
7장 - c#2.0 - 그외  (0) 2014.12.28
7장 - c#2.0 - 제네릭  (0) 2014.12.25