๋๋ค์
:์ต๋ช ๋ฉ์๋
๋ฅผ ๋ง๋ค๊ธฐ ์ํด ์ฌ์ฉํ๋ ์๋๋ค์
์ผ๋ก ๋ง๋ค์ด์ง์ต๋ช ๋ฉ์๋
๋ฅผ๋ฌด๋ช ํจ์(Anonymous Function)
๋ผ๊ณ ํ๋ค.
๋๋ค์ ์ ์ธ ํ์
๋งค๊ฐ๋ณ์ ๋ชฉ๋ก => ์
=>
์ฐ์ฐ์๋ฅผ ์ ๋ ฅ ์ฐ์ฐ์๋ผ๊ณ ํ๋ค.
delegate int AAA(int x, int y);
static void Main(string[] args){
AAA aaa = (int x,int y) => x + y;
}
(int x, int y) => x + y
๋ผ๋์ต๋ช ๋ฉ์๋
๊ฐdelegate
์ธaaa
์ ์ ๋ฌ๋๊ณ ์๋ ๋ชจ์ต์์ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ด ๋ฐ๊ฟ์ ์ฌ์ฉ ๊ฐ๋ฅ
AAA aaa = (x, y) => x + y;
delegate์ ์ธ์์ ํ์ ์ด ์ ์ธ๋์ด ์๊ธฐ์ ๊ฐ๋ฅ
์์ ์ต๋ช ๋ฉ์๋(๋ฌด๋ช ํจ์)๋ ๊ธฐ์กด์ ์ต๋ช ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ๋ณด๋ค ๊ฐ์ํ ๋์๋ค.
๊ธฐ์กด ๋ธ๋ฆฌ๊ฒ์ดํธ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ์
delegate int AAA(int x, int y);
static void Main(string[] args){
AAA aaa = delegate(int x, int y)
{
return x+y;
}
}
์ฝ๋ ์ฌ์ฉ ์์ 1
using System.Collections;
namespace LambdaEx
{
class Program
{
delegate int Sum(int x, int y);
static void Main(string[] args)
{
Sum sum = (x, y) => x + y;
Console.WriteLine($"{sum(10, 20)}");
}
}
}
๋๋ค์์ ๋ ๋ค๋ฅธ ํํ
- ์ ์ธํ์๋ค .. ? => ๋ค์ํ๊ฒ ์ฌ์ฉ๋ ๋ฏ
๋งค๊ฐ๋ณ์๋ชฉ๋ก => {
์คํ์ฝ๋ ...
}
๋๋ฆฌ์ ์ธ์คํด์ค = () => { ... ์คํ์ฝ๋ ... }
// ๋งค๊ฐ๋ณ์๊ฐ ์๋ ๋ฌด๋ช
ํจ์
๋๋ฆฌ์ ์ธ์คํด์ค = (๋งค๊ฐ๋ณ์) => { ... ์คํ์ฝ๋ ... }
// ๋งค๊ฐ๋ณ์๊ฐ ์๋ ๋ฌด๋ช
ํจ์
์ฌ์ฉ์์ ์ฝ๋
using System.Collections;
namespace LambdaEx
{
class Program
{
delegate string SumString(string[] args);
static void Main(string[] args)
{
SumString ss = (str) =>
{
string result = "";
foreach (string s in str)
{
result += s;
}
return result;
};
Console.WriteLine(ss(args));
}
}
}
.exe
ํ์ผ์ ์คํ์์ผ ์ ๋ ฅ์ ์ฃผ๋ฉด ํด๋น ์ ๋ ฅ์ ์ด์ด๋ถ์ธstring
๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅ.
๋๋ค์ ์ฌ์ฉ์์ ์ฝ๋ ์ถ๊ฐ
class Program
{
delegate int Calculate(int a , int b);
delegate string Concatenate(string[] strs);
static void Main(string[] args)
{
// ์ ํ์์ ๋๋ค์
Calculate cal1 = (a, b) => a + b;
Console.WriteLine("{0} + {1} = {2}",3,4,cal1(3,4));
// ๋ฌธ ํ์์ ๋๋ค์
Concatenate concat = (arr) =>
{
string result = "";
foreach (string str in arr)
{
result += str;
}
return result;
};
string[] txt = {"์๋ฒ์ง๊ฐ","๋ฐฉ์", "๋ค์ด๊ฐ์ ๋ค" };
Console.WriteLine("์๋ฒ์ง๊ฐ ๋ฐฉ์ ๋ค์ด๊ฐ์ ๋ค => {0}", concat(txt));
}
}
Output
3 + 4 = 7
์๋ฒ์ง๊ฐ ๋ฐฉ์ ๋ค์ด๊ฐ์ ๋ค => ์๋ฒ์ง๊ฐ๋ฐฉ์๋ค์ด๊ฐ์ ๋ค
Func ์ Action ์ ์ฌ์ฉํ ๋ฌด๋ช ํจ์ ์ ์ธ
- ๊ธฐ์กด ์ต๋ช
ํจ์ ํน์ ๋ฌด๋ช
ํจ์๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๋งค๋ฒ ๋ณ๊ฐ์ ๋ธ๋ฆฌ๊ฒ์ดํธ๋ฅผ ์ ์ธํด์ผํ๋ ๋ฒ๊ฑฐ๋ก์์ด ์๋ค.
- MS๋ ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด
.Net
ํ๋ ์์ํฌ์Func
์Action
๋ธ๋ฆฌ๊ฒ์ดํธ๋ฅผ ๋ฏธ๋ฆฌ ์ ์ธ ํด๋์๋ค. Func ๋ธ๋ฆฌ๊ฒ์ดํธ
=> ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ๊ธฐ ์ํดAction ๋ธ๋ฆฌ๊ฒ์ดํธ
=> ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ์ง ์๋ ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ๊ธฐ ์ํด
- MS๋ ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด
Func ๋ธ๋ฆฌ๊ฒ์ดํธ
- ์ ์ธํ์
public delegate TResult Func<out TResult>()
public delegate TResult Func<in T1, out TResult>(T arg)
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2)
...
16๊ฐ ์ธ์๋ฅผ ๊ฐ์ง ๊ฒ๊น์ง..
- ๋ชจ๋
Func
๋ธ๋ฆฌ๊ฒ์ดํธ์ ํ์ ๋งค๊ฐ๋ณ์ ์ค ๊ฐ์ฅ ๋ง์ง๋ง์ ์๋ ๊ฒ์ด ๋ฐํํ์์ด๋ค.
- ๊ฐ๋จํ ์ฌ์ฉ์์
Func<int> func1 = () => 10;
// ์
๋ ฅ ๋งค๊ฐ๋ณ์๋ ์์ผ๋ฉฐ ๋ฌด์กฐ๊ฑด intํ๊ฐ์ธ 10์ ๋ฐํ
Console.WriteLine(func1()); // 10 ์ถ๋ ฅ
Func<int, int> func2 = (x) => x * 2;
//์
๋ ฅ ๋งค๊ฐ๋ณ์๋ int ํ์ ํ๋, ๋ฐํ ํ์๋ int
Console.WriteLine(func2(3)); // 6 ์ถ๋ ฅ
Func<int,int,int> func3 = (x,y) => x + y;
//์
๋ ฅ ๋งค๊ฐ๋ณ์๋ int ํ์ ๋, ๋ฐํ ํ์๋ int
Console.WriteLine(func3(2,3)); // 5 ์ถ๋ ฅ
Func ๋ธ๋ฆฌ๊ฒ์ดํธ ์ฌ์ฉ ์์ ์ฝ๋
using System;
namespace FuncTest
{
class MainApp
{
static void Main(string[] args)
{
Func<int> func1 = () => 10;
// ์
๋ ฅ ๋งค๊ฐ๋ณ์๋ ์์ผ๋ฉฐ ๋ฌด์กฐ๊ฑด intํ๊ฐ์ธ 10์ ๋ฐํ
Console.WriteLine(func1()); // 10 ์ถ๋ ฅ
Func<int, int> func2 = (x) => x * 2;
//์
๋ ฅ ๋งค๊ฐ๋ณ์๋ int ํ์ ํ๋, ๋ฐํ ํ์๋ int
Console.WriteLine(func2(3)); // 6 ์ถ๋ ฅ
Func<int, int, int> func3 = (x, y) => x + y;
//์
๋ ฅ ๋งค๊ฐ๋ณ์๋ int ํ์ ๋, ๋ฐํ ํ์๋ int
Console.WriteLine(func3(2, 3)); // 5 ์ถ๋ ฅ
}
}
}
Output
10
6
5
Action ๋ธ๋ฆฌ๊ฒ์ดํธ
Action
๋ธ๋ฆฌ๊ฒ์ดํธ๋Func
์ ๊ฑฐ์ ๋น์ทํ๋ค.- ์ฐจ์ด์ ์ด๋ผ ํ๋ฉด
Action
๋ธ๋ฆฌ๊ฒ์ดํธ์ ๊ฒฝ์ฐ์๋ ๋ฐํ ํ์์ด ์๋ค.
- ์ ์ธํ์
public delegate void Action<>()
public delegate void Action<in T>(T1 arg)
public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2)
...
16๊ฐ ์ธ์๋ฅผ ๊ฐ์ง ๊ฒ๊น์ง..
Action ๋ธ๋ฆฌ๊ฒ์ดํธ ์ฌ์ฉ ์์ ์ฝ๋
using System;
namespace ActionTest
{
class MainApp
{
static void Main(string[] args)
{
Action act1 = () => Console.WriteLine("Action()");
act1();
int result = 0;
Action<int> act2 = (x) => result = x * x;
act2(3);
Console.WriteLine("result : {0}", result);
Action<double, double> act3 = (x, y) =>
{
double pi = x / y;
Console.WriteLine("Action<T1, T2>({0}, {1}) : {2}", x, y, pi);
};
act3(22.0, 7.0);
}
}
}
Output
Action()
result : 9
Action<T1, T2>(22, 7) : 3.142857142857143
Func & Action ํตํฉ ์์ ์ฝ๋
using System;
class MainApp
{
static void Main(string[] args)
{
Func<int> func1 = () => 10;
// ์
๋ ฅ ๋งค๊ฐ๋ณ์๋ ์์ผ๋ฉฐ ๋ฌด์กฐ๊ฑด intํ๊ฐ์ธ 10์ ๋ฐํ
Console.WriteLine(func1()); // 10 ์ถ๋ ฅ
Func<int, int> func2 = (x) => x * 2;
//์
๋ ฅ ๋งค๊ฐ๋ณ์๋ int ํ์ ํ๋, ๋ฐํ ํ์๋ int
Console.WriteLine(func2(3)); // 6 ์ถ๋ ฅ
Func<int, int, int> func3 = (x, y) => x + y;
//์
๋ ฅ ๋งค๊ฐ๋ณ์๋ int ํ์ ๋, ๋ฐํ ํ์๋ int
Console.WriteLine(func3(2, 3)); // 5 ์ถ๋ ฅ
Action act1 = () => Console.WriteLine("Action()");
act1();
int result = 0;
Action<int> act2 = (x) => result = x * x;
act2(3);
Console.WriteLine("result : {0}", result);
Action<double, double> act3 = (x, y) =>
{
double pi = x / y;
Console.WriteLine("Action<T1, T2>({0}, {1}) : {2}", x, y, pi);
};
act3(22.0, 7.0);
}
}
Output
10
6
5
Action()
result : 9
Action<T1, T2>(22, 7) : 3.142857142857143
์ ํธ๋ฆฌ (Expression Tree)
์
์ํธ๋ฆฌ
๋ก ํํํ์๋ฃ๊ตฌ์กฐ
Expression
ํด๋์ค์ ํ์ํด๋์ค๋ค์ ์ด์ฉํด ์ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๋ค.
ํฉํ ๋ฆฌ ๋ฉ์๋(Factory Method)
ํฉํ ๋ฆฌ ๋ฉ์๋๋ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ์ผ์ ๋ด๋นํ๋ ๋ฉ์๋๋ฅผ ๊ฐ๋ฆฌํค๋ ์ฉ์ด์ด๋ค.
C#์๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ์์ฑ์ ๋ฉ์๋๊ฐ ์๊ธดํ์ง๋ง ๊ฐ๋์ ์ด๊ฒ๋ง์ผ๋ก ์ถฉ๋ถํ์ง ์์ ๋๊ฐ ์๋ค.
๊ฐ์ฒด์ ์์ฑ์ ๋ณต์กํ ๋
ผ๋ฆฌ๊ฐ ํ์ํ ๊ฒฝ์ฐ, ๊ฐ์ฒด ์์ฑ ๊ณผ์ ์ ๋ณ๋์ ๋ฉ์๋์ ๊ตฌํํด ๋์ผ๋ฉด ์ฝ๋์ ๋ณต์ก๋๋ฅผ ์๋นํ ์ค์ผ ์ ์๋ค.
Expression ํด๋์ค์ ์ ์ ํฉํ ๋ฆฌ ๋ฉ์๋๋ค์ Expression ํด๋์ค์ ํ์ ํด๋์ค์ธ ConstantExpression,
BinaryExpression ํด๋์ค ๋ฑ์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํจ์ผ๋ก์จ ์๊ณ ๋ฅผ ์ค์ฌ์ค๋ค.
1*2+(x-y)
์์ ํธ๋ฆฌ๋ก ๋ง๋ ํ ์ปดํ์ผ ํ๋ ์์ ์ฝ๋
using System;
using System.Linq.Expressions;
namespace UsingExpressionTree
{
class MainApp
{
static void Main(string[] args)
{
// 1 * 2 + (x - y)
Expression const1 = Expression.Constant(1);
Expression const2 = Expression.Constant(2);
Expression leftExp = Expression.Multiply(const1, const2);
Expression param1 = Expression.Parameter(typeof(int)); // x ๋ฅผ ์ํ ๋ณ์
Expression param2 = Expression.Parameter(typeof(int)); // y ๋ฅผ ์ํ ๋ณ์
Expression rightExp = Expression.Subtract(param1, param2);
Expression exp = Expression.Add(leftExp, rightExp);
Expression<Func<int,int,int>> expression = Expression<Func<int,int,int>>.Lambda<Func<int,int,int>>(exp, new ParameterExpression[]
{
(ParameterExpression)param1,
(ParameterExpression)param2,
});
Func<int,int,int> func = expression.Compile();
//x = 7, y = 8
Console.WriteLine("1 * 2 + ({0} - {1}) = {2}", 7, 8, func(7,8));
}
}
}
Output
1 * 2 + (7 - 8) = 1
๋๋ค์์ ์ด์ฉํด์ ์ ํธ๋ฆฌ๋ฅผ ๋ง๋๋ ์์ ์ฝ๋
using System;
using System.Linq.Expressions;
namespace UsingExpressionTree
{
class MainApp
{
static void Main(string[] args)
{
Expression<Func<int,int,int>> expression = (a,b) => 1 * 2 + (a - b);
Func<int,int,int> func = expression.Compile();
//x = 7, y = 8
Console.WriteLine("1 * 2 + ({0} - {1}) = {2}", 7, 8, func(7, 8));
}
}
}
Output
1 * 2 + (7 - 8) = 1
- ์์ ๋ง๋ ์ฝ๋์ ๋นํด์ ํจ์ฌ ๊ฐ๋จํ๊ฒ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋์ถํ ์ ์๋ค.
- ํ์ง๋ง ์ด ๊ฒฝ์ฐ์๋
๋์ ์ผ๋ก
์ ํธ๋ฆฌ๋ฅผ ๋ง๋ค๊ธฐ๋ ์ด๋ ต๋ค. Expression
ํ์์๋ถ๋ณ(Immutable)
์ด๊ธฐ ๋๋ฌธ์ ํ ๋ฒ ์ธ์คํด์ค๊ฐ ๋ง๋ค์ด์ง๊ณ ๋ ํ์๋ ๋ณ๊ฒฝํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
'๐ป Programming Language > C#' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
40. LINQ ๊ธฐ๋ณธ ๋ฌธ๋ฒ (0) | 2022.04.08 |
---|---|
39. LINQ ์ฌ์ฉํด๋ณด๊ธฐ (0) | 2022.04.08 |
37. ๋ธ๋ฆฌ๊ฒ์ดํธ๋ฅผ ํตํ ์ด๋ฒคํธ ์ฒ๋ฆฌ (0) | 2022.04.08 |
36. ์ต๋ช ๋ฉ์๋ (0) | 2022.04.08 |
35. ๋ธ๋ฆฌ๊ฒ์ดํธ ์ฒด์ธ(delegate chain) (0) | 2022.04.08 |