C# Delegate (Action, Func, Event)
๐ซ Q
- ๋๋ฆฌ์
- ๋๋ฆฌ์๋ฅผ ์ ์ธํ๊ณ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
- ๋๋ฆฌ์๊ฐ ์ฌ์ฉ๋๋ ์ด์ ์ ์ํฉ
- ์ผ๋ฐํ ๋๋ฆฌ์๋ฅผ ์์ฑํ๊ณ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
- ์ต๋ช ๋ฉ์๋๋ฅผ ์ ์ธํ๊ณ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
- ์ด๋ฒคํธ๋ฅผ ์ ์ธํ๊ณ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
๐ซ Delegate | ๋๋ฆฌ์
๋ฉ์๋์ ์ฐธ์กฐ.
Like ํจ์ ํฌ์ธํฐ in C/C++.
๋ฉ์๋๋ฅผ ๋ณ์์ฒ๋ผ ์ธ ์ ์๊ฒ ํด์ค๋ค !
๋ฉ์๋๋ฅผ ๋ณ์์ ํ ๋นํ๊ณ , ๋ค๋ฅธ ๋ฉ์๋์ ์ธ์๋ก ์ ๋ฌํ๊ฑฐ๋ ๋ฐํ ๊ฐ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
์ฃผ๋ก ์ด๋ฒคํธ ์ฒ๋ฆฌ, ๋น๋๊ธฐ ์ฒ๋ฆฌ, ์ฝ๋ฐฑ ํจ์๋ฅผ ๊ตฌํํ ๋ ์ฌ์ฉ๋๋ค.
๐ซง Delegate ๊ตฌํ
delegate ๋ฐํํ์
MyDelegate(๋งค๊ฐ๋ณ์);
๊ฐ์ ๋ชจ์์ผ๋ก ์ ์ธํ๋ค.
๋งค๊ฐ๋ณ์๋ ํ์ํ ๋งํผ ์ ์ธํ ์ ์๋ค. (0 ~ 16๊ฐ)
์ฃผ์ !!
delegate
๋ int
, string
๊ฐ์ ํ์(Type)์ด๋ฏ๋ก,
โ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ๋ ๊ทธ ๋ฌด์โ์ ๋ง๋ค๋ ค๋ฉด ์ธ์คํด์ค๋ฅผ ๋ฐ๋ก ๋ง๋ค์ด์ผ ํ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// ์ ์ธ
delegate void MyDelegate(string msg);
// ์ ์
void Method1(string msg) => Console.WriteLine(msg);
// ์ธ์คํด์ค ์์ฑ
MyDelegate myDelegate = new MyDelegate(Method1);
// ํธ์ถ
myDelegate("Hello, World!");
// Output :
// Hello, World!
๐ซง Delegate Why?
โ๊ฐโ์ด ์๋ โํ๋โ, โ์ฝ๋โ ์์ฒด๋ฅผ ์ ๋ฌํ๊ณ ์ถ์ ๋๊ฐ ์๋ค.
์๋ฅผ ๋ค์ด ๋ฐฐ์ด์ ์ ๋ ฌํ๋ ๋ฉ์๋๋ฅผ ๋ง๋ค ๋,
์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํ ์ง, ๋ด๋ฆผ์ฐจ์์ผ๋ก ์ ๋ ฌํ ์ง, ํน๋ณํ ๊ณ์ฐ์์ ์ธ์ง..
์ ๋ ฌ์ ์ํํ ๋ ์ฌ์ฉํ๋ ๋น๊ต ๋ฃจํด์ ๋งค๊ฐ ๋ณ์๋ก ๋ฃ์ ์ ์๋ค๋ฉด?
์ด๋ฐ ๊ณ ๋ฏผ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ํ๋ก๊ทธ๋๋จธ๊ฐ ์์์ ๊ฒฐ์ ํ ์ ์๋ค.
๐ซง Delegate ์ผ๋ฐํ
๋ณดํต ๋ฉ์๋ ๋ฟ๋ง ์๋๋ผ, ์ผ๋ฐํ ๋ฉ์๋๋ ์ฐธ์กฐํ ์ ์๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ์ ์ธ
// IComparable : ๋น๊ต ๊ฐ๋ฅํ ํ์
(์์นํ, ๋ฌธ์์ด)
// IComparable.CompareTo() : ๋น๊ต ๋ฉ์๋ (1, 0, -1)
delegate T MyDelegate<T>(T a, T b) where T : IComparable;
// ์ ์
int Add(int a, int b) => a + b;
float Add(float a, float b) => a + b;
// ์ธ์คํด์ค ์์ฑ
MyDelegate<int> myDelegate1 = Add;
MyDelegate<float> myDelegate2 = Add;
// ํธ์ถ
int result1 = myDelegate(1, 2);
float result2 = myDelegate(1.0f, 2.0f);
// Output :
// 3
// 3.0
๐ซง Delegate ์ฒด์ธ
ํ๋์ delegate
์ ์ฌ๋ฌ ๋ฉ์๋๋ฅผ ํ ๋นํ ์ ์๋ค.
๊ทธ๋ ๊ฒ ํ ๋นํ ์ฌ๋ฌ ๋ฉ์๋๋ฅผ ํ๋ฒ์ ํธ์ถํ ์ ์๋ค. (๋ฉํฐ์บ์คํธ)
ํธ์ถ ์์๋ ํ ๋น๋ ์์๋๋ก ํธ์ถ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// ์ ์ธ
delegate void MyDelegate(string msg);
// ์ ์
void Method1(string msg) => Console.WriteLine(msg);
void Method2(string msg) => Console.WriteLine(msg);
// ์ธ์คํด์ค ์์ฑ
MyDelegate myDelegate;
// 1. ํ ๋น (+=) / ํด์ (-=)
myDelegate += Method1;
myDelegate += Method2;
// 2. ํ ๋น (+) / ํด์ (-)
myDelegate = Method1 + Method2;
// 3. ํ ๋น (Delegate.Combine) / ํด์ (Delegate.Remove)
myDelegate = (MyDelegate) Delegate.Combine(
new MyDelegate(Method1),
new MyDelegate(Method2));
// ํธ์ถ
myDelegate("Hello, World!");
// Output :
// Hello, World!
// Hello, World!
๐ซง Delegate ์ต๋ช ๋ฉ์๋ / ๋ฌด๋ช ํจ์ ํ์ฉ
์ต๋ช ๋ฉ์๋์ ๋ฌด๋ช ํจ์๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
์ฐธ๊ณ ๋ก ์ต๋ช
๋ฉ์๋๋ C# 2.0์์, ๋ฌด๋ช
ํจ์๋ C# 3.0์์ ๋์
๋์๋ค.
๋ฌด๋ช
ํจ์๊ฐ ํธ๋ฆฌํ์ง๋ง, ํ์ ํธํ์ฑ์ ์ ์งํ๊ธฐ ์ํด ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ ๋ชจ๋ ์ง์ํ๊ณ ์๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// ์ ์ธ
delegate void MyDelegate(string msg);
// ์ธ์คํด์ค ์์ฑ
MyDelegate myDelegate;
// ์ต๋ช
๋ฉ์๋ ํ ๋น
myDelegate = delegate (string msg) { Console.WriteLine(msg); };
// ๋ฌด๋ช
ํจ์ ํ ๋น
myDelegate += (string msg) => { Console.WriteLine(msg); };
// ํธ์ถ
myDelegate("Hello, World!");
// Output :
// Hello, World!
// Hello, World!
๐ซง Delegate ๋น๋๊ธฐ ์ฒ๋ฆฌ (Invoke/BeginInvoke)
Invoke
๋ BeginInvoke
, EndInvoke
๋ฅผ ์ด์ฉํด ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๋ค.
์ธ ์๋ ์์ง๋ง ์ค๋๋ ๋ฐฉ์์ด๋ฏ๋ก, ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ Task
๋ฅผ ์ฐ๋ ๊ฒ์ด ๋ ๋ฐ๋์งํ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// https://www.csharpstudy.com/Threads/async-delegate.aspx
// ์ ์ธ ๋ฐ ์ธ์คํด์ค ์์ฑ
Func<int, int, int> work = GetArea;
// ์ ์
int GetArea(int height, int width)
{
int area = height * width;
return area;
}
// ๋น๋๊ธฐ ์ฒ๋ฆฌ
IAsyncResult asyncRes = work.BeginInvoke(10, 20, null, null);
int result = work.EndInvoke(asyncRes);
๐ซ ์ผ๋ฐํ๋ Delegate
์ผ์ผ์ด delegate
๋ฅผ ์ ์ํ๋ ๊ฒ์ด ๋ฒ๊ฑฐ๋กญ๋ค๋ฉด,
Action
, Func
, Predicate
๋ฑ์ ์ฌ์ฉํ ์ ์๋ค.
๐ซง Action
delegate
์ ์ผ๋ฐํ๋ก, ๋ฐํ ๊ฐ์ด ์๋(void
) ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ ์ ์๋ delegate
.
๋งค๊ฐ๋ณ์๋ 0 ~ 16๊ฐ๊น์ง ์ ์ธํ ์ ์๋ค.
๊ทธ ์ด์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, ref
๋ out
ํ์ ์๋ก ์์๋ ๋งค๊ฐ ๋ณ์๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ๋ผ๋ฉด ์ง์ ๋ณ๋์ ๋๋ฆฌ์๋ฅผ ๋ง๋ค์ด ์จ์ผํ๋ค.
1
2
3
4
5
Action<string> myAction = (msg) => Console.WriteLine(msg);
myAction("Hello, World!"); // Hello, World!
Action<int, int> myAction = (a, b) => a + b;
myAction(1, 2); // 3
๐ซง Func
delegate
์ ์ผ๋ฐํ๋ก, ๋ฐํ ๊ฐ์ด ์๋(void
์ ์ธ) ๋ฉ์๋๋ฅผ ์ฐธ์กฐํ ์ ์๋ delegate
.
๋งค๊ฐ๋ณ์๋ 0 ~ 16๊ฐ๊น์ง ์ ์ธํ ์ ์๊ณ , ๋ง์ง๋ง ๋งค๊ฐ๋ณ์๊ฐ ๋ฐํ ๊ฐ์ด ๋๋ค.
๊ทธ ์ด์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, ref
๋ out
ํ์ ์๋ก ์์๋ ๋งค๊ฐ ๋ณ์๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ๋ผ๋ฉด ์ง์ ๋ณ๋์ ๋๋ฆฌ์๋ฅผ ๋ง๋ค์ด ์จ์ผํ๋ค.
1
2
Func<int, int, int> myFunc = (a, b) => a + b;
myFunc(1, 2); // 3
๐ซง Predicate
Func
์ ํน์ํ ํํ๋ก, ๋ฐํ ๊ฐ์ด bool
์ธ delegate
.
ํ๋์ ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐ์ bool
๊ฐ์ ๋ฐํํ๋ค.
1
2
Predicate<int> myPredicate = (num) => num > 0;
myPredicate(1); // True
๐ซ Event | ์ด๋ฒคํธ
์ด๋ฒคํธ(์ฌ๊ฑด)
๋ฅผ ๊ตฌํํ๊ธฐ ์ํด ๋ช ๊ฐ์ง ์ ์ฝ์ ๊ฐ์ง, ๋ํ๋ delegate
.
์ด๋ฒคํธ | ๊ฐ์ฒด์ ์ผ์ด๋ ์ฌ๊ฑด ์๋ฆฌ๊ธฐ
๊ฐ์ฒด์ ์ํ ๋ณํ, ์ฌ๊ฑด์ ๋ฐ์์ ๋ค๋ฅธ ๊ฐ์ฒด๋ ๋ฉ์๋์ ์๋ฆฌ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค.
๋ค๋ฅธ ๊ฐ์ฒด๋ ๋ฉ์๋์์ ์ด๋ฒคํธ๋ฅผ ๊ตฌ๋
ํ๊ณ , ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์๋ฆผ์ ๋ฐ์ ์ฒ๋ฆฌํ ์ ์๋ค.
๐ซง Event๊ฐ Delegate์ ๋ค๋ฅธ ์
event
๋ ์ธ๋ถ์์ ์ง์ ํธ์ถํ ์ ์๋ค.delegate
๋public
์ด๋internal
๋ก ์์๋์ด ์์ผ๋ฉด ๊ฐ๋ฅํ๋ค.
delegate
๋interface
๋ด๋ถ์์ ์ฌ์ฉํ ์ ์์ง๋ง,event
๋interface
๋ด๋ถ์์ ์ฌ์ฉํ ์ ์๋ค.event
๋delegate
์ ์ธ์คํด์ค์ด๊ธฐ ๋๋ฌธ์ด๋ค.
๐ซง Event ๊ตฌํ
delegate
๋ฅผ event
ํค์๋๋ก ์์ํด์ ์ ์ธํ๋ค.
์ด๋ ์์๋๋ delegate
๋ ํด๋์ค ๋ฐ์ ์ ์ธํด๋ ๋๊ณ ์์ ์ ์ธํด๋ ๋๋ค.
event
๋ ์ ์ธํ delegate
์ ์ธ์คํด์ค์ด๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// delegate ์ ์ธ (ํด๋์ค ๋ฐ์ ์ ์ธํด๋ ๋๋ค.)
delegate void MyDelegate(string msg);
// Publisher
class MyClass
{
// ์ด๋ฒคํธ ์ ์ธ (MyDelegate์ ์ธ์คํด์ค)
public event MyDelegate MyEvent;
// ๊ตฌ๋
& ๊ตฌ๋
ํด์
public void Subscribe(MyDelegate myDelegate) => MyEvent += myDelegate;
public void Unsubscribe(MyDelegate myDelegate) => MyEvent -= myDelegate;
// ์ด๋ฒคํธ ๋ฐ์ (์ด๋ฒคํธ๋ ํด๋์ค ๋ด๋ถ์์๋ง ํธ์ถ ๊ฐ๋ฅ)
public void OnEvent(string msg) => MyEvent?.Invoke(msg);
}
// Subscriber
class Program
{
static void Main()
{
MyClass myClass = new MyClass();
myClass.Subscribe(MyMethod);
myClass.OnEvent("Hello, World!");
// ์๋์ฒ๋ผ ์ด๋ฒคํธ๋ฅผ ์ธ๋ถ์์ ์ง์ ํธ์ถ ํ ์ ์๋ค.
// myClass.MyEvent?.Invoke("Hello, World!");
}
static void MyMethod(string msg) => Console.WriteLine(msg);
}
๐ซ ๋ฉ๋ชจ/์ฐธ๊ณ
- callback์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ.
- delegate๋ ์์ด๋ก โ๋๋ฆฌ์ธโ, โ์ฌ์ โ ์ด๋ผ๋ ๋ป์ด ์๋ค.
delegate
๋ฅผ ์ด์ฉํด ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ผ๊ธ ๊ฐ์ฒด๋ก์์ ํจ์ ๊ฐ๋ ์ ๊ตฌํํ ์ ์๋ค.delegate
(event
)๋ฅผ ์ด์ฉํด ์ด๋ฒคํธ, ์ต์ ๋ฒ ํจํด์ ๊ตฌํํ ์ ์๋ค.- โ์ด๊ฒ์ด C#์ด๋ค.โ, โMSDNโ
TODO: ์ด๋ฒคํธ ๊ธฐ๋ฐ ํ๋ก๊ทธ๋๋ฐ
- Lambda-Expression