[ C# ] 람다함수
Delegate
= 메서드 번지를 저장하거나 다른 메서드의 인수로 메서드 자체를 전달하고 싶을 때 사용
C++의 포인터와 비슷하다
지정자 : 클래스에 소속되는 델리게이트일 때 지정자를 앞에 붙힌다
형식 인수 이름을 꼭 붙여야된다 - int X , int num O
클래스가 선언될 수 있는 모든 곳에 델리게이트 선언 가능하다
지정자 delegate 리턴타입 이름(인수목록)
delegate void deleA(int num)
자체로 메서드를 가리킬 수 없어 인스턴스 생성 후 메서드를 가르키도록 초기화 해야됨
→ 특정 메서드를 가르킬땐 그 대상 메서드를 호출할 수 있다
delegate void dele(int a);
class Class4
{
public static void Meth1(int a) { Console.WriteLine("call 1" + a); }
public static void Meth2(int a) { Console.WriteLine("call 2" + a); }
public static void Main()
{
dele d;
d = new dele(Meth1);
d(12);
d = new dele(Meth2);
d(34);
Console.ReadLine();
}
}
dele 타입의 객체d를 선언하고 meth1, meth2을 가르키는 인스턴스를 각각만들었다
대입할 때 마다 매번 생성자를 호출하지만 참조되지 않는 인스턴스는 가비지 컬렉터가 알아서 지운다

C++ 의 포인터는 전역 메소드만 가리킬 수 있지만 델리게이트는 클래스에 속한 모든 메소드를 가리킬 수 있다
사용 목적 : 속도를 줄이고, 코드를 간결하게 하기위해서
델리게이트 사용하지 않을 때
class Class5
{
public static int Add(int a,int b) { return a + b; }
public static int Mul(int a, int b) { return a * b; }
public static void Main()
{
int a = 3; int b= 5;
int o;
Console.WriteLine("어떤 연산을 하고싶습니까? 1덧셈 2곱셈");
o = Convert.ToInt32(Console.ReadLine());
switch(o)
{
case 1:
Console.WriteLine("결과 {0} 입니다", Add(a, b));
break;
case 2:
Console.WriteLine("결과 {0} 입니다", Mul(a, b));
break;
}
}
}
switch문과 같은 조건문을 작성할 때 속도가 느려지고 가독성이 좋지 않다
델리게이트 사용할 때
delegate int dele(int a, int b);
class Class6
{
public static int Add(int a, int b) { return a + b; }
public static int Mul(int a, int b) { return a * b; }
public static void Main()
{
dele[] R = { Add, Mul };
int a = 3; int b = 5;
int o;
Console.WriteLine("어떤 연산을 하고싶습니까? 1덧셈 2곱셈");
o = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("결과 {0} 입니다", R[o - 1](a, b));
Console.ReadLine();
}
}
객체 R에 두 메서드에 대한 참조를 저장하여 사용자로 부터 입력받은 첨자를 R에 바로 적용해 호출한다

익명 타입, 익명 함수
익명 타입 : 타입선언 후 객체 생성할 필요 없이 타입 정의, 객체 생성을 한번에 처리
var 객체 = new { p1=v1, p2=v2 };
목적: 한번만 사용할 타입를 생성할 때 사용하기 위해서
익명 타입 없이 타입 생성할 때
class human
{
public string Name { get; set; }
public human(string Name)
{
this.Name = Name;
}
}
class Class1
{
static void Main()
{
human H = new human("안녕");
Console.WriteLine("이름 : "+ H.Name);
}
}
익명타입으로 생성할 때
internal class Class3
{
public static void Main()
{
var Lee = new { Name = "안녕" };
Console.WriteLine("이름 : " + Lee.Name);
}
}
class 또 생성하는 것을 줄일 수 있다
익명타입은 컴파일러에서 마음대로 이름을 붙이기 때문에 이 타입은 참조 할 수 없다
익명 함수 : 한번만 호출되는 메서드를 간결하게 델리게이트를 활용하여 사용
delegate(인수 목록) {메서드 코드};
delegate(int a ,b) {return a+b};
뒤에 꼭 세미콜론을 붙여야됨
목적 : 한번만 호출되는 메서드를 메서드를 만들지 않고도 사용하게 하기 위해서
익명 함수없이 생성할때
delegate int dele(int a, int b);
class Class7
{
public static int Add(int a, int b) { return a + b; }
public static void Main()
{
dele d = Add;
int k = d(2, 3);
Console.WriteLine(k);
Console.ReadLine();
}
}
Add 메서드를 생성한 후 호출해야됨
익명함수를 사용할 때
delegate int dele(int a, int b);
class Class8
{
public static void Main()
{
dele d = delegate (int a, int b) { return a + b; };
int k = d(2, 3);
Console.WriteLine(k);
Console.ReadLine();
}
}
Add메소드 생성 없이 바로 실행시킬 수 있다
람다함수
= 익명 메서드와 유사하지만 인수 타입을 생략할 수 있고, 표현식을 쓸 수 있고, 표현식을 트리로도 변환할 수 있다
익명함수 형식) delegate(int a){return a+1;};
람다함수 형식) a=> a + 1;
인수 타입은 위에 델리게이션 선언으로 a가 int인지 판별 가능하다
delegate 키워드가 사라지고 람다 표현식인 =>을 사용한다 뒤에는 return을 생략하고 실행 명령어를 입력한다
람다함수 예제
delegate int dele1(int a, int b);
delegate int dele2();
delegate void dele3();
class Class9
{
public static void Main()
{
dele1 d1 = (x, y) => x + y;
int b = d1(4, 5);
Console.WriteLine(b);
dele2 d2 = () => 1234;
int c = d2();
Console.WriteLine(c);
dele3 d3 = () => { Console.WriteLine("안녕"); };
d3();
Console.ReadLine();
}
}
목적 : delegate 키워드, 인수타입, return문등 형식을 맞추기 위해 번거로운 것들을 제거하여 익명 메서드를 압축한다