람다식
함수형 프로그래밍의 근간이 되는 람다 계산법에서 사용하는 식을 말한다.
C#에서 표현하는 람다식은 매개변수_목록 => 식 으로 표현된다.
- 예시
delegate int Function(int a, int b);
static void Main(string[] args)
{
Function func = (int a, int b) => a + b;
}
컴파일러는 람다의 매개 변수의 타입을 지정하지 않아도 타입 유추를 통해 가능하다면 람다 함수를 생성할 수 있다.
Function func = (a, b) => a + b;
단일 실행문장이 아닌 여러 세미 콜론을 사용하는 문의 경우 중괄호를 이용하여 그 안에 실행하는 문장을 표현한다.
Function func = (a, b) =>
{
int c = a + b;
int d = a * b;
return d / c;
};
Func과 Action 대리자 타입
Func 대리자는 반환 타입이 있는 함수를 명명할 수 있는 타입이다.
public delegate TResult Func<out TResult>();
public delegate TResult Func<in T, out TResult>(T arg);
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
타입 정의를 보면 타입 매개변수의 마지막 값은 항상 반환 형식이다.
Func<float, float, float, float> Length = (float a, float b, float c) =>
{
return MathF.Sqrt(a * a + b * b + c * c);
};
float len = Length(5.0f, 3.0f, 4.0f);
Action 대리자는 반환 타입이 없는 함수를 명명할 수 있는 타입이다.
public delegate void Action<>()
public delegate void Action<in T>(T arg)
public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2)
public delegate void Action<in T1, in T2, in T3>(T1 arg1, T2 arg2, T3 arg3)
Action<string> PrintMessage = (string msg) => Console.WriteLine($"{msg}");
표현식 트리 (Expression Tree)
계산식과 같은 표현 식을 트리 형태로 구성하고 런타임에 해당 식을 컴파일하여 실행할 수 있는 기능이다.
ex) x + 1 표현식 : + 연산자 부모에 "x" 파라미터 자식과 1 이라는 상수를 두고 있는 표현식 트리라고 할 수 있다.
모든 표현식 개체는 System.Linq.Expressions.Expressio 개체를 상속하며 연산이나 파라미터, 상수를 표현하기 위해 파생 클래스를 생성하여 사용한다.
Expression.XXX()는 구체저인 표현식 노드를 생성하는 팩토리 메서드 방식으로 제공한다.
- x + 1를 표현하는 방법
Expression const1 = Expression.Constant(1);
Expression param1 = Expression.Parameter(typeof(int), "x");
Expression exp = Expression.Add(const1, param1);
표현식의 컴파일과 실행
최종 표현식이 되는 트리의 부모는 컴파일까지 해야 실행할 수 있는 의미를 지닌다. 해당 표현식은 람다식으로 만들어 람다식을 컴파일하는 구조이다.
람다식 또한 Expression의 파생 클래스로 타입을 Func<> 혹은 Action<>으로 지칭하여 생성한다.
Expression.Lambda()라는 생성 메서드를 활용해서 표현식과 매개변수를 생성 매개변수로 전달하면 람다식을 만들 수 있다.
// 람다식으로 전환
// 표현식과 매개변수가 필요
Expression<Func<int, int>> lambda1 = Expression<Func<int, int>>.Lambda<Func<int, int>>
(exp, // 표현식
new ParameterExpression[] { (ParameterExpression)param1 } // 매개변수 인자
);
컴파일은 해당 람다식 객체의 Compile()를 호출하며 람다식의 타입으로 지정했던 대리자 형식의 인스턴스를 얻을 수 있다. 대리자 인스턴스를 사용하여 해당 표현식을 실행한다.
Func<int, int> compiledExp = lambda1.Compile();
Console.WriteLine(compiledExp(3));
Expression-Bodied Member 식으로 이루어지는 멤버
C#에서 람다식의 => 표현을 멤버의 메서드, 프로퍼티에 사용할 수 있다.
메서드에서 사용
class FriendList
{
private List<string> list = new List<string>();
public void Add(string name) => list.Add(name);
public void Remove(string name) => list.Remove(name);
}
기본 메서드는 위와 같이 해당 메서드를 호출할 때 실행하는 함수를 지칭할 수 있다.
세미콜론을 둘 이상 포함해야하는 실행문은 지칭할 수 없다.
프로퍼티에서 사용
읽기 전용 프로퍼티와 인덱서는 다음과 같이 작성하며 get을 생략할 수 있다.
public int Capacity => list.Capacity; // 읽기 전용
public string this[int index] => list[index]; // 읽기 전용
읽기 쓰기가 가능한 프로퍼티와 인덱서는 다음과 같이 작성한다.
public int Capacity { get => list.Capacity; set => list.Capacity = value; }
public string this[int index] { get => list[index]; set => list[index] = value; }
'C# > C# 기본' 카테고리의 다른 글
[C#] 리플렉션과 애트리뷰트 (0) | 2021.10.19 |
---|---|
[C#] LINQ (0) | 2021.10.18 |
[C#] 대리자와 이벤트 (0) | 2021.10.15 |
[C#] Generic 프로그래밍 / 예외 처리 (0) | 2021.10.12 |
[C#] 배열 / 컬렉션 / 인덱서 (0) | 2021.10.11 |