914 Appendix i
슈퍼히어로의 은유
#9 익명 유형, 익명 메서드, 람다 표현식
C#에서는 명시적인 선언 없이도 값의 유형과 메서드를 생성할 수 있습니다. 이름 없이 선언된 값 유형이나 메서드를 익명(anony-
mous)이라고 하는데, 이는 매우 강력한 도구입니다. 아마 익명 유형이나 메서드가 없었다면 LINQ는 세상에 나오지 못했을 겁니다.
프로그래밍 언어의 기초적인 개념을 확실히 잡았다면, 익명 유형, 익명 메서드, 람다 표현식을 자유자재로 다루는 것은 매우 쉽습니
다. 이 책에서 짤막하게 다루는 익명 유형과 익명 메서드 혹은 람다 표현식은 그리 어렵지 않을 겁니다. 그럼 익명이란 것에 대해 간
단히 소개하는 것부터 시작해 보죠.
class Program {
delegate void MyIntAndString(int i, string s);
delegate int CombineTwoInts(int x, int y);
static void Main(string[] args) {
/*
* * 컴파일 시점에 객체의 유형을 IDE가 결정하도록 var 키워드가 어떻게 하는지 15장에 나왔었죠
*
* 또한 var와 new 를 사용해서 묻지마 유형의 객체를 생성할 수 있습니다.
*
* 익명 유형에 관해 더 알고 싶다면
* http://msdn.microsoft.com/en-us/library/bb397696.aspx 를 방문해 보세요
*/
// Guy와 매우 흡사한 익명 유형을 생성합니다.
var anonymousGuy = new { Name = "Bob", Age = 43, Cash = 137 };
// 이 부분을 입력하면, 인텔리센스가 자동으로 멤버들을 골라줍니다.
// Name, Age, Cash가 인텔리센스 창에 나타납니다
Console.WriteLine("{0} is {1} years old and has {2} bucks",
anonymousGuy.Name, anonymousGuy.Age, anonymousGuy.Cash);
// 출력 결과: Bob is 43 years old and has 137 bucks
// 익명 유형의 인스턴스는 ToString() 메서드를 갖고 있습니다.
Console.WriteLine(anonymousGuy.ToString());
// 출력 결과: { Name = Bob, Age = 43, Cash = 137 }
/*
* 11장에서, 여러분은 메서드를 참조하기 위해 대리자를 어떻게 사용할 수 있는지 배웠습니다.
*
* 지금까지 학습했던 모든 대리자 예제에서는 기존 메서드를 대리자에 할당했습니다.
*
* 익명 메서드는 하나의 문장에서 선언하는 메서드로, 익명 유형처럼 { }를 사용해서 선언합니다.
* 익명 함수에 대해 더 알고 싶다면
* http://msdn.microsoft.com/en-
us/library/0yw3tz5k.aspx를 방문해 보세요.
*/
/*
* var 키워드가 IDE가 컴파일 시점에 객체의 유형을 결정하는 것을 14장에서 봤습니다.
*
* 또한 var와 new를 사용해서 묻지마 유형의 객체를 생성할 수 있습니다.
*
* 익명 유형(형식)에 관해 더 알고 싶다면
* http://msdn.microsoft.com/ko-kr/library/bb397696.aspx를 방문하세요.
*/
/*
* 15장에서 여러분은 메서드를 참조하는 대리자의 사용법을 배웠습니다.
* 지금까지 학습했던 모든 대리자 예제에서는 기존 메서드를 대리자에 할당했습니다.
*
* 익명 메서드는 하나의 문장에서 선언하는 메서드로, 익명 유형처럼 { }를 사용해서 선언합니다.
*
* 익명 메서드(무명 메서드)에 대해서 더 알고 싶다면, 아래의 웹 사이트를 방문해 보세요.
* http://msdn.microsoft.com/ko-kr/library/0yw3tz5k.aspx
*/
지금 여기예요
� 915
남은 것들
// 콘솔 상에 int와 string을 출력하는 익명 메서드가 여기 나와 있습니다. 이 메서드의 선언부는 //
// MyIntAndString 대리자(위에서 선언한)와 일치하므로
// MyIntAndString 유형의 변수에 이 대리자를 할당할 수 있습니다.
MyIntAndString printThem = delegate(int i, string s)
{ Console.WriteLine("{0} - {1}", i, s); };
printThem(123, "four five six");
// 출력 결과: 123 - four five six
// 동일한 시그내처(int, string)를 가진 또 다른 익명 메서드가 나와 있는데, 이 메서드는 해당 문자열이 int를
// 포함하고 있는지 검사합니다.
MyIntAndString contains = delegate(int i, string s)
{ Console.WriteLine(s.Contains(i.ToString())); };
contains(123, "four five six");
// 출력 결과: False
contains(123, "four 123 five six");
// 출력 결과: True
// 동일한 시그네처(int, string)를 가진 또 다른 익명 메서드가 나와 있는데,
// 이 메서드는 해당 문자열이 int를 포함하고 있는지 검사합니다.
Delegate d = contains;
d.DynamicInvoke(new object[] { 123, "four 123 five six" });
// 출력 결과: True
/*
* 람다 표현식(lambda expression)은 => 연산자를 사용하는 특별한 종류의 익명 메서드입니다.
* 람다 연산자라고 불리긴 하지만, 일반적으로 “~가 된다(goes to)”라고 읽으므로
* 람다 표현식이라는 말을 더 많이 사용합니다. 여기에 간단한 람다 표현식이 나와 있군요.
*
* (a, b) => { return a + b; }
*
* “a와 b는 a 더하기 b가 된다”라고 읽는데, 이것은 두 값을 더하는 익명 메서드입니다.
* 람다 표현식은 매개변수를 가져다 값을 반환하는 익명 메서드라고 생각해도 무방합니다.
*
* 람다(표현)식에 대해 더 알고 싶다면, 아래의 웹 사이트를 방문해 보세요.
* http://msdn.microsoft.com/ko-kr/library/bb397687.aspx
*/
// 두 수를 더하는 람다 표현식이 나와 있는데 이 식의 시그네처는 CombineTwoInts 대리자와
// 일치하므로, 이를 CombineTwoInts 유형의 대리자 변수에 할당할 수 있습니다. CombineTwoInts가
// int형을 반환한다는 점에 주목하세요. 이는 람다 표현식도 int를 반환해야 한다는 뜻입니다.
CombineTwoInts adder = (a, b) => { return a + b; };
Console.WriteLine(adder(3, 5));
// 출력 결과: 8
// 또 다른 람다 표현식이 있군요. 이번에는 두 수를 곱합니다.
CombineTwoInts multiplier = (int a, int b) => { return a * b; };
Console.WriteLine(multiplier(3, 5));
// 출력 결과: 15
// LINQ와 함께 람다 표현식을 결합하면 매우 유용한 것들을 할 수 있습니다. 여기에 대한 간단한 예제가 나와 있군요.
var greaterThan3 = new List<int> { 1, 2, 3, 4, 5, 6 }.Where(x => x > 3);
foreach (int i in greaterThan3) Console.Write("{0} ", i);
// 출력 결과: 4 5 6
Console.ReadKey();
}
}
Get Head First C# (개정3판): 상상을 초월하는 객체지향 C# 학습법 now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.