람다는 보통 작성한 곳에서 한번만 쓰는 일회성 함수(= 무명함수)를 만들때 사용합니다.
때문에 함수를 최대한 간결하게 표현하는것을 위해 만들어졌고
필요없는것을 제거하고 남은것이 '매개변수'와 '식' 입니다.
매개변수_목록 => 식
매개변수 목록은 함수에서 쓰는 매개변수를 입력하면됩니다.
식은 함수에서 {} 안에 쓰는 로직을 입력하면됩니다.
간단한 함수를 람다로 표현하면 가독성을 증가시킬 수 있습니다.
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); //친구 삭제
}
델리게이트를 편리하게 사용하기 위해서 나온 문법이 Action 대리자와 Func 대리자입니다.
이전 시간에는 델리게이트 체인을 만들어서 이벤트로 사용했던 Action 대리자를 배웠습니다.
Func 대리자는 결과를 반환하는 메소드를 참조하기 위해 만들어 졌으며
17개의 메소드가 오버로딩 되어있습니다.
Func 대리자는 Action과 달리 반드시 반환값을 return해야합니다.
Func 대리자는 람다식으로 간편하게 사용할때 이용합니다.
매개변수의 데이터 형식으로 이용합니다.

테스트를 위해 Func 인스턴스를 생성했습니다.
접근 제한자를 용도에 맞게 설정하고,
Func<>괄호 안에 매개변수 개수에 맞춰 데이터 형식을 작성합니다.
(마지막 매개변수는 출력 전용 매개변수 out 입니다.)
매개변수를 넣지 않는다고 해도 항상 1개의 데이터 타입을 작성해야 하는데,
이 데이터 타입에는 반환값의 타입을 넣어야 합니다.
참고
두개 이상 부터는 항상 마지막 데이터 형식이 반환값의 타입입니다.
Func는 항상 마지막 데이터형식이 out이 되도록 오버로딩 되어있기 때문입니다.
예) int, int, int => 앞 int 두 개는 매개변수의 형식, 마지막 int는 반환값의 형식입니다.
그리고 Add함수와 Sub함수를 콜백함수로 등록시켜보겠습니다.
(Action과 마찮가지로 System을 using 선언해 줘야 합니다.)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System; // 필수!!
public class Func대리자 : MonoBehaviour
{
public Func<int,int,int> myFunc; //Func 인스턴스 생성
void Start()
{
myFunc += Add; //콜백함수 등록
myFunc += Sub; //콜백함수 등록
int num = 0;
num += myFunc(1, 2); //인수에 1,2를 넣고 실행
Debug.Log($"num = {num}");
}
//===========콜백함수로 사용할 Add,Sub=============
public int Add(int a, int b)
{
Debug.Log($"a + b = {a + b}");
return a + b;
}
public int Sub(int a, int b)
{
Debug.Log($"a - b = {a - b}");
return a - b;
}
}
결과는 어떻게 될까요?
1+2를 num에 더하고, 1-2를 한번더 더해서, 3-1인 2가 나와야 할것같지만

처음에 실행된 Add 함수는 num에 더해지지 않았고❌,
마지막에 실행된 Sub 함수만 num에 담겨서 출력됐습니다.👌
(Add가 출력된것을 보면 Add 함수가 실행되지않은것도 아닙니다.)
이렇게 Func를 델리게이트 체인으로 만들면 마지막 함수의 결과만 반환합니다.
그래서 Func는 델리게이트 체인으로 사용하지 않고,
람다식으로 무명함수를 만들어 넣고 쓰고 싶을 때 쓰는 방법으로 사용하거나,
매개변수의 데이터 형식으로 이용합니다.
람다식을 사용하면
Action과 Func에 더욱 편하게 콜백함수를 등록할 수 있습니다.
간단한 함수의 경우 람다식을 만들어 바로 등록할수 있기 때문에 자주 사용됩니다.

Action에는 반환값이 없는 람다를 등록하여야 하고,

Func에는 반환값이 있는 람다를 넣어야합니다.
참고 : Func는 반환값이 반드시 필요한데, return이 안보입니다.
이유는 한줄로 끝나는 간단한 식은 {}를 제외할 수 있으며
반환값이 필요한 함수의 경우에는 return이 없어도
문장을 닫으면 반환값으로 인지합니다. (형식유추 덕분입니다.)
람다식도 {}안에 식을 적을 수 있습니다. 이것을 "문 형식의 람다" 라고합니다.
전체 코드
using System;
public class Action대리자 : MonoBehaviour
{
public Action myAction = () => Debug.Log("W키가 눌렸습니다.");
void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
myAction();
}
}
}
public class Func대리자 : MonoBehaviour
{
public Func<int, int, int> myFunc = (a, b) => a + b;
void Start()
{
Debug.Log(myFunc(1, 2)); // 3 출력
}
}
함수 매개변수에는 (int num)같이 넣어야할 데이터 타입을 만들어줍니다.
그리고 우리는 여기에 정수를 넣겠죠? 0 이나 498 같은 숫자를 넣을겁니다.
그럼 이 매개변수 타입을 (Func func1)이렇게 지정한다면 우리는 무엇을 넣어야할까요?
여기엔 반환값이 있는 함수를 넣어주면 됩니다.
public Func<int, int, int> myFunc = (a, b) => a + b;
void Start()
{
myMethod(myFunc); // 인자로 같은 타입의 Func를 넣었음.
}
public void myMethod(Func<int,int,int> func)
{
// 어떤 일
}