C#

[C#]메서드를 매개 변수로 전달(Func, Action, Predicate)

DevStory 2021. 9. 22.

C#에서는 대리자(delegate)를 사용하여 메서드를 매개 변수로 전달할 수 있는 기법이 존재합니다.

 

바로 Func 대리자, Action 대리자, Predicate 대리자를 사용하여 전달할 수 있습니다.

 

이번 포스팅에서는 C#에서 메서드를 매개 변수로 전달할 수 있게 해주는 Func, Action, Predicate 대리자를 소개합니다.

 


Func 대리자

Func 대리자는 0~16개의 입력 매개 변수가 존재하며, 반환 값이 존재합니다.

 

Func 대리자는 다음과 같이 .Net FrameWork에 선언되어 있습니다.

public delegate returnType Func<in inputType, out returnType>(InputType arg);

returnType

반환 타입입니다.

 

in

in 뒤에는 매개 변수의 자료형을 정의합니다.

 

out

out 뒤에는 메서드의 반환 타입을 정의합니다.

 

InputType

메서드의 매개 변수입니다.

 

아래 코드는 Func 대리자가 AddFunc 메서드를 대신 실행하는 예제입니다.

public static string AddFunc(int a, int b)
{
  return (a + b).ToString();
}

static void Main(string[] args)
{
  Func<int, int, string> funcDelegate = AddFunc;

  Console.WriteLine(funcDelegate(10, 20)); // 30
}

아래는 대리자 funcDelegate가 AddFunc 메서드를 참조하는 과정입니다.

1. AddFunc 메서드의 반환 타입인 string은 Func 대리자 꺾새( <> )의 마지막에 위치합니다.

만약, 메서드의 반환 타입과 꺾새의 마지막의 반환 타입이 일치하지 않은 경우 컴파일 에러가 발생합니다.

 

2. AddFunc 메서드의 매개 변수는 int a, int b입니다. Func 대리자 꺾새( <> )의 앞에서부터 매개 변수의 자료형을 순서대로 작성합니다.

 

아래는 메서드의 매개 변수가 존재하지 않은 경우 Func 대리자로 메서드를 참조하는 예제입니다.

public static string PrintFunc()
{
  return "Hello";
}

static void Main(string[] args)
{
  Func<string> funcDelegate = PrintFunc;

  Console.WriteLine(funcDelegate()); // Hello
}

PrintFunc 메서드는 string을 반환하며, 매개 변수가 존재하지 않기 때문에 Func 대리자의 꺾새( <> )에는 PrintFunc메서드의 반환 타입인 string만 작성합니다.

 

다음은 Func 대리자의 반환 타입이 void인 메서드를 참조하는 경우입니다.

public static void PrintFunc()
{
  return;
}

static void Main(string[] args)
{
  Func<void> funcDelegate = PrintFunc;
}

Func 대리자는 아무것도 반환하지 않는 메서드를 참조하는 경우 즉, 반환 타입이 void인 경우 컴파일 에러가 발생합니다.

 

다음은 메서드를 매개 변수로 전달하는 코드입니다.

public static string AddFunc (int a, int b)
{
  return (a + b).ToString();
}

public static string SubFunc (int a, int b)
{
  return (a - b).ToString();
}

public static void PrintFunc(Func<int, int, string> Calc, int a, int b)
{
  Console.WriteLine(Calc(a, b));
}

static void Main(string[] args)
{
  PrintFunc(AddFunc, 100, 200); // 300
  PrintFunc(SubFunc, 200, 100); // 100
}

 

Func 대리자의 주의사항으로는 Func 대리자는 입력 매개 변수의 개수가 16개를 초과하는 경우 컴파일 에러가 발생합니다.

public static string AddFunc (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15, int a16, int a17)
{
  return "17개의 매개 변수";
}

public static void PrintFunc(Func<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, string> Calc)
{
  Console.WriteLine(Calc(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17));
}

static void Main(string[] args)
{
  PrintFunc(AddFunc);
}

입력 매개 변수의 개수가 16개를 초과하는 경우 컴파일 에러 내용으로 원인을 찾기 어렵기 때문에 주의하도록 합니다. 


Action 대리자

Action 대리자는 0~16개의 입력 매개 변수를 가지며, 반환 값이 없는 로직을 처리할 때 사용할 수 있습니다.

 

반환 값이 없다는 점을 제외하고는 Func 대리자와 동일하므로 자세한 설명은 생략합니다.

 

아래는 반환 타입이 없는 메서드를 매개 변수로 전달하는 코드입니다.

public static void PrintSubFunc(int a, int b)
{
  Console.WriteLine((a - b).ToString());
}

public static void PrintFunc(Action<int, int> Func, int a, int b)
{
  Func(a, b);
}

static void Main(string[] args)
{
  PrintFunc(PrintAddFunc, 100, 200); // 300
  PrintFunc(PrintSubFunc, 200, 200); // 0
}

Predicate 대리자

Predicate 대리자는 Action, Func 대리자와 비슷하지만 반환 타입이 bool형이고 입력 매개 변수의 개수가 무조건 1개인 경우 사용할 수 있는 대리자입니다.

 

반환 타입이 bool형으로 고정되어 있으므로 Func 대리자와 달리 꺾새( <> )에 반환 타입을 명시하지 않습니다.

 

다음은 반환 타입이 bool형이고 int형 입력 매개 변수를 가지는 메서드를 매개 변수로 전달하는 코드입니다.

public static bool BoolFunc(int age)
{
  if (age > 19)
    return true;
  else
    return false;
}

public static void PrintFunc(Predicate<int> Func, int age)
{
  if (Func(age))
    Console.WriteLine("20살 이상");
  else
    Console.WriteLine("20살 미만");
}

static void Main(string[] args)
{
  PrintFunc(BoolFunc, 30); // 20살 이상
  PrintFunc(BoolFunc, 10); // 20살 미만
}

정리

Func 대리자

  • 0~16개의 입력 매개 변수를 가지며, void형을 제외한 반환 타입을 가지는 메서드를 참조하는 대리자

 

Action 대리자

  • 0~16개의 입력 매개 변수를 가지며, 반환 타입이 void형인 메서드를 참조하는 대리자

 

Predicate 대리자

  • 무조건 1개의 입력 매개 변수를 가지며, 반환 타입이 bool형인 메서드를 참조하는 대리자
반응형

댓글