C# 이것저것/초보자를 위한 C#200제

[C#] 람다식(Lambda Expression)

agingcurve 2024. 2. 1. 15:24
반응형

람다식은 익명 메서도를 간단하게 표현이 가능하다. 람다식은 개체로 처리되는 코드이며, 메서드와 같이 매개변수와 리턴 값을 갖는다.

람다식은 인수를 메서드에 전달 가능하며, 값을 반환할 수 있다.

 

람다식은 델리게이트로 표현될 수 있는 코드인데, 델리게이트형은 리턴 값이 파라미터 갯수가 에따라 정해진다. 

리턴값이 없는 람다식은 Action 델리게이트에 해당하고, 리턴값이 있는 람다식은 Func 델리게이트에 해당된다.

 

두 개 파라미터를 갖고 리턴 값이 없는 람다식은 Action<T1, T2> 델리게이트에 해당한다.

한 개의 파라미터와 리턴 값을 갖는 람다식은 Func<T, TResult> 델리게이트에 해당한다.

 

람다식 연산자는 "=>"로 표현이 된다. 

=> 연산자 왼쪽은 매개변수, 오른쪽은 식 또는 문장이 위치하며, 이것이 리턴값이 된다.

예를 들어 x => x * x는 매개변수 x 에 대해 x의 제곱을 리턴하는 람다식이다.

C#3.0이후 부터는 람다식이 도입되며 익명메서드를 쓸 일이 없어졌다.

람다식이 훨씬 간단하기 때문이다.

int n = Count(arr, delegate (int x) {return x % 2 == 0;});

 

이를 람다식으로 표현하면 다음과 같이 쓸 수 있다.

int n = Count(arr, x => x % 2 == 0);

 

 

deleggate, Func, Action으로 정의 된 메서드를 만들 수 있으며 "=>" 람다 연산자의 오른쪽에 식이 올 수 있고, 문장이 올 수 있다.

 

(1) 식 람다(Expression Lambda)

연산자의 오른쪽에 식이 있는 것을 식 람다라고 한다. 식 람다는 식의 결과를 반환하며 기본형식은 다음과 같다.

(input-parameters) => expression

 

괄호는 람다 식에 입력 매개변수가 하나뿐인 경우에만 생략이 가능하고 그렇지 않으면 생략이 불가능하다.

Action line = () => Console.WriteLine(); // 1)
Func<int, int, bool> testForEquality = (x, y) => x == y; // 2)
Func<int, string, bool> isToolLong = (int x, string s) -> s.Length > x; // 3)

 

1) 입력 매개변수가 0개면 빈 괄호 지정함

2) 둘 이상의 입력 매개변수는 괄호를 묶고 쉼표로 구분해야 함

3) 컴파일러에서 입력 형식을 유추할 수 없을 때, 형식을 명시적으로 지정가능

 

(2) 문 람다(Statement Lambda)

문 람다는 중괄호 안에 문장을 지정한다는 점에서 식 람다와 비슷하다. 문 람다의 본문에 지정할 수 있는 문장의 갯수는 제한이 없지만 일반적으로 2~3개만 지정한다.

(input-parameters) => { statement; }

 

리턴 값이 없고 매개변수가 하나인 메서드를 문 람다로 작성할 경우, 해당 처럼 작성 가능하다

Action<string> greet = name =>
{
	string greeting = $"Hello {name}!";
    Console.WriteLine(greeting);
}

 

greet("World"); 라고 호출하면 "Hello World" 라고 출력한다.

 

3개의 델리게이트를 정의해보자

square는 하나의 정수를 매개변수로 하고 리턴 값이 Func 델리게이트 이다. square(5)는 5의 제곱을 리턴한다.

using System;
using System.Linq;

namespace A117_LambdaXamples
{
    class Program
    {
        delegate double CalcMehtod(double a, double b);
        delegate bool IsTeenAger(Student student);
        delegate bool IsAdult(Student student);

        static void Main(string[] args)
        {
            Func<int, int> square = x => x * x;
            Console.WriteLine(square(5));

            int[] numbers = { 2, 3, 4, 5 };
            var squareNumbers = numbers.Select(x => x * x); //정수배열에 각요소 제곱해 할당
            Console.WriteLine(string.Join(" ", squareNumbers));

            Action line = () => Console.WriteLine(); //Action 델리게이트로 매개변수 없이 출력
            line(); //빈줄 한줄 출력

            CalcMehtod add = (a, b) => a + b;
            CalcMehtod subtract = (a, b) => a - b;

            Console.WriteLine(add(100, 200));
            Console.WriteLine(subtract(10.5, 20));

			// isTeen은 IsTeenAger 델리게이트이며, Student 객체를 매개변수로 함
            // 나이가 12보다 크로 20보다 작으면 true를 리턴

			IsTeenAger isTeen = delegate (Student s) { return s.Age > 12 && s.Age < 20; }; 

            Student s1 = new Student() { Name = "John", Age = 18 };
            Console.WriteLine("{0} 은 {1}.", s1.Name, isTeen(s1) ? "청소년입니다":"청소년이 아닙니다.");

            IsAdult isAdult = (s) => { int adultAge = 18; return s.Age >= adultAge; };

            Student s2 = new Student() { Name = "Robin", Age = 20 };
            Console.WriteLine("{0}은 {1}.", s2.Name, isAdult(s2) ? "성인입니다" : "성인이 아닙니다");

        }

        public class Student
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }
    }
}