2020. 1. 29. 19:14ㆍC# 언어/이것이 C# 이다. 책정리
챕터14 '람다식' 입니다
익명 메소드를 만드는 또 다른 방법과, 람다식의 정의를 배웁니다.
'이것이 C#이다' 교재를 바탕으로 정리했습니다.
이전 정리글
2020/01/06 - [이것이 C# 이다./이것이 C# 이다. 책정리] - Ch01 프로그래밍을 시작합시다.
2020/01/06 - [이것이 C# 이다./이것이 C# 이다. 책정리] - Ch02 처음 만드는 C# 프로그램
2020/01/06 - [이것이 C# 이다./이것이 C# 이다. 책정리] - Ch03 데이터 보관하기
2020/01/07 - [이것이 C# 이다./이것이 C# 이다. 책정리] - 부록A. 문자열 다루기
2020/01/07 - [이것이 C# 이다./이것이 C# 이다. 책정리] - Ch04. 데이터를 가공하는 연산자
2020/01/08 - [이것이 C# 이다./이것이 C# 이다. 책정리] - Ch05 코드의 흐름 제어하기
2020/01/09 - [이것이 C# 이다./이것이 C# 이다. 책정리] - ch06 메소드로 코드 간추리기
2020/01/11 - [이것이 C# 이다./이것이 C# 이다. 책정리] - ch07 클래스
2020/01/17 - [이것이 C# 이다./이것이 C# 이다. 책정리] - ch08 인터페이스와 추상 클래스
2020/01/18 - [이것이 C# 이다./이것이 C# 이다. 책정리] - ch09 프로퍼티
2020/01/19 - [이것이 C# 이다./이것이 C# 이다. 책정리] - ch10 배열과 컬렉션, 그리고 인덱서
2020/01/23 - [이것이 C# 이다./이것이 C# 이다. 책정리] - ch11 일반화 프로그래밍
ㅇ 람다식, 너는 어디에서 왔니? |
람다식은 알론조 처치(Alonzo Church) 라는 수학자가 1936년에 발표한
"람다 계산법" 에서 사용하는 식입니다.
수학 기초론을 연구하던 중에 분명하고 간결한 방법으로 함수를 묘사하기 위해 람다 계산법을 고안해 냈습니다.
람다 계산법은 크게 함수의 정의와 변수, 그리고 함수의 적용으로 이루어져 있는데,
이 계산법에서는 모든 것이 함수로 이루어져 있습니다.
어떤 값을 변수에 대입하고 싶으면 함수를 변수에 대입하며, 이것을
"함수의 적용" 이라고 부릅니다.
ㅇ 처음 만나는 람다식 |
람다식은 익명 메소드를 만들기 위해 사용합니다.
람다식으로 만드는 익명 메소드는 "무명 함수" 라는 이름으로 부릅니다.
람다식의 선언 예입니다.
class MainApp
{
delegate int Calculate(int a, int b);
static void Main()
{
Calculate calc = (int a, int b) => a + b;
}
}
"=>" 연산자는 "입력" 연산자 입니다.
역할은 그저 매개 변수를 전달하는 것뿐입니다.
람다식을 이용하여 간결한 코드가 되었습니다. 그리고 이 뿐만이 아니라
c# 컴파일러는 위 코들르 한층 더 간결하게 만들 수 있도록
"형식 유추"라는 기능을 제공합니다. 매개 변수의 형식을 제거할 수 있죠.
형식 유추의 예입니다.
class MainApp
{
delegate int Calculate(int a, int b);
static void Main()
{
Calculate calc = ( a, b) => a + b;
}
}
우리는 앞서 13장에서 대리자를 이용한 익명 메소드를 만들었습니다.
코드의 양이 상당히 많이 줄었음을 느낄 수 있습니다.
대리자를 이용한 익명 메소드구현입니다.
using System;
using System.Collections;
using static System.Console;
namespace ex
{
class MainApp
{
delegate int Calculate(int a, int b);
static void Main()
{
Calculate calc = delegate (int a, int b)
{
return a + b;
};
}
}
}
그렇다면, 마이크로소프트는 어째서 익명 메소드를 만드는 방법을 더 번거로운 방법(대리자)
과 더 편리한 방법(람다식)을 같이 제공하고 있는걸 까요?
마이크로소프트는 대리자를 이용한 익명 메소드를 C# 2.0에 도입했는데,
람다식은 C# 3.0에 와서야 도입했기 때문입니다. 이미 수많은 프로그램들이
C# 2.0으로 작성된 상황에서 C# 3.0이 나왔다고 언어의 기능을 뺄 수 없기 때문입니다.
ㅇ 문 형식의 람다식 |
문 형식의 람다 식은 => 연산자의 오른편에 식 대신 { }로 둘러싸인 코드 블록이 위치합니다.
예제 코드로 바로 보겠습니다.
문 형식의 람다식
using System;
using static System.Console;
namespace p461
{
class Program
{
// 주석 처리된 코드는 예제의 출력방식이 다르기 때문입니다.
// 책에 쓰여진 대로 코딩을했다면
// C\ (경로) (아버지가 방에 들어가신다.) 처럼 경로 뒤에 바로 써주셔야됩니다.
// 예제 입력을 원하시면 주석으로 적용시켜주시면 됩니다.
delegate string Concatenate(string[] args);
static void Main(string[] args)
{
// string[] input = ReadLine().Split();
Concatenate concat =
(arr) =>
{
string result = "";
foreach (var s in arr)
{
result += s;
}
return result;
};
// WriteLine(concat(input));
WriteLine(concat(args));
}
}
}
ㅇ Func와 Action으로 더 간편하게 무명 함수 만들기 |
익명 메소드와 무명 함수는 코드를 보다 간결하게 만들어주는 요소입니다.
하지만 이들은 대부분의 경우 단 하나의 익명 메소드나 무명 함수를 만들기 위해
매번 별개의 대리자를 선언해야 합니다.
이를 해결하기 위해 마이크로소프트는 Func와 Action 대리자를 미리 선언해뒀습니다.
Func 대리자는 결과를 반환하는 메소드를 참조 하고
Action 대리자는 결과를 반환하지 않는 메소드를 참조 합니다.
Func 대리자
Func 대리자는 결과를 반환하는 메소드를 참조하기 위해 만들어졌습니다.
.NET 프레임워크에는 모두 17가지 버전의 Func 대리자가 준비되있습니다.
모든 Func 대리자의 형식 매개 변수 중 가장 마지막에 있는 것이 반환 형식입니다.
Func의 예제 프로그램입니다.
using System;
using static System.Console;
namespace pp464
{
class Program
{
static void Main(string[] args)
{
Func<int> func1 = () => 10;
WriteLine($"func1() : {func1()}");
Func<int, int> func2 = (x) => x * 2;
WriteLine($"func2() : {func2(2)}");
Func<double, double, double> func3 = (x, y) => x / y;
WriteLine($"func3(22,7) : {func3(22, 7)}");
}
}
}
Action 대리자
Func와 거의 똑같습니다. 차이점이라면 Action 대리자는 반환 형식이 없다는 것뿐입니다.
Action 대리자 또한 17가지의 버전으로 선언되있습니다.
Action 예제 프로그램입니다.
using System;
using static System.Console;
namespace pp464
{
class Program
{
static void Main(string[] args)
{
Action act1 = () => WriteLine("Action()");
act1();
int result = 0;
Action<int> act2 = (x) => result = x * x;
act2(3);
WriteLine($"result = {result}");
Action<double, double> act3 = (x, y) =>
{
double pi = x / y;
WriteLine($"Action<T1, T2>({x},{y}) : {pi}");
};
act3(22.0, 7.0);
}
}
}