Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
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
Archives
Today
Total
관리 메뉴

nomad-programmer

[Programming/C#] Func 대리자, Action 대리자 본문

Programming/C#

[Programming/C#] Func 대리자, Action 대리자

scii 2020. 9. 23. 23:22

Func와 Action을 사용하는 이유? Func와 Action으로 더 간편한 무명 함수를 만들 수 있다.

익명 메소드와 무명 함수는 코드를 보다 간결하게 만들어주는 요소들이다. 하지만 대부분의 경우 단 하나의 익명 메소드나 무명 함수를 만들기 위해 매번 별개의 대리자를 선언해야 한다. 번거로운 일이 아닐 수 없다. 이 문제를 해결하기 위해 MS는 .NET 프레임워크에 Func와 Action 대리자를 미리 선언해뒀다.

  • Func 대리자는 결과를 반환하는 메소드를 참조한다.
  • Action 대리자는 결과를 반환하지 않는 메소드를 참조한다.

Func 대리자

Func 대리자는 결과를 반환하는 메소드를 참조하기 위해 만들어졌다. .NET 프레임워크에는 모두 17가지 버전의 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 대리자의 형식 매개 변수 중 가장 마지막에 있는 것이 반환 형식이다. 형식 매개 변수가 하나뿐인 Func는 그 하나가 반환 형식이고, 형식 매개 변수가 두 개인 Func는 두 번째, 세 개인 Func는 세 번째, 그리고 17개인 Func는 열일곱 번째가 반환 형식으로 사용된다.

Func 대리자는 입력 매개 변수가 하나도 없는 것부터 16개에 이르는 것까지 버전이 다양하기 때문에 어지간한 경우가 아니면 별도의 대리자를 만들어 쓸 필요가 없다.
다만 입력 매개 변수가 16개 이상이라든지, ref나 out 한정자로 수식된 매개 변수를 사용해야 하는 경우라면 사용자 정의로 대리자를 만들어 사용해야 한다.

// 입력 매개 변수가 없으며, 무조건 5를 반환
Func<int> func1 = () => 5;

// 매개 변수가 하나 있는 버전의 Func<T1, TResult>
Func<int, int> func2 = (x) => 2 * x;

// 매개 변수가 두개 있는 버전의 Func<T1, T2, TResult>
Func<int, int, int> func3 = (x, y) => x + y;

Func 대리자의 예제

using System;

namespace test
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            Func<int> func1 = () => 5;
            Console.WriteLine(func1());

            Func<int, int> func2 = (x) => x * 2;
            Console.WriteLine(func2(5));

            Func<double, double, double> func3 = (x, y) => x / y;
            Console.WriteLine(func3(14, 6));
        }
    }
}


/* 결과

5
10
2.33333333333333

*/

Action 대리자

Action 대리자는 Func 대리자와 거의 흡사하다. 차이점이라면 Action 대리자는 반환 형식이 없다는 것뿐이다. Action 대리자는 Func 대리자처럼 17개의 버전이 .NET 프레임워크에 선언되어 있다.

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 대리자의 형식 매개 변수는 모두 입력 매개 변수를 위해 선언되어 있다. 그 이유는 Func와 달리 어떤 결과를 반환하는 것을 목적으로 하지 않고, 일련의 작업을 수행하는 것이 목적이기 때문이다.
Action 대리자는 매개 변수가 없는 버전에서부터 16개의 버전까지 준비되어 있기 때문에 필요로 하는 대부분의 경우에 사용이 가능하다.

// 매개 변수가 아무것도 없는 Action
Action act1 = () => Console.WriteLine("Action()");

// 매개 변수가 하나뿐인 Action<T>, 람다식 밖에 선언된 result에 값 저장
int result = 0;
Action<int> act2 = (x) => result = x * x;

// 매개 변수가 두 개인 Action<T1, T2>
Action<double, double> act3 = (x, y) => 
     {
         double pi = x / y;
         Console.WriteLine("Action<T1, T2>(0}, {1}) : {2}", x, y, pi);
     };   

Action 대리자의 예제

using System;

namespace test
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            Action act1 = () => Console.WriteLine("Action()");
            act1();

            int result = 0;
            Action<int> act2 = (x) => result = x * x;
            act2(5);
            Console.WriteLine($"result: {result}");

            Action<double, double> act3 = (x, y) =>
            {
                double pi = x / y;
                Console.WriteLine($"Action<T1, T2>({x}, {y}): {pi}");
            };
            act3(17.0, 8.0);
        }
    }
}


/* 결과

Action()
result: 25
Action<T1, T2>(17, 8): 2.125

*/
Comments