다음의 내용은 델리게이트와 무명 메소드, 람다식을 알아야 이해할 수 있으므로 이전 강좌를(C# 고급강좌) 한번 보시길 바랍니다.
Func? Action?
프로그램을 작성하던 중에 갑자기 무명 메소드가 필요해졌다고 생각해보자.
무명 메소드를 사용하기 위해서는 이를 참조할수 있는 델리게이트 변수가 있어야 하며, 또한 델리게이트 변수를 생성하기에 앞서 델리게이트 타입을 선언해야한다.
그러면 각기 다른 타입의 무명 메소드를 여러개 만들때는 어떻게 해야할까?
당연히 무명 메소드마다 그 타입에 맞는 델리게이트 타입과 변수를 따로 따로 선언해야 할 것이다. 이는 매우 비효율적인 작업이기 대문에, C#에서는 Func,Action 이라는 델리게이트를 제공한다.
Func와 Action은 미리 선언된 델리게이트 변수 로써 별도의 선언없이 사용가능한다.
Func는 반환값이 있는 메소드를 참조하는 델리게이트 변수이고, Action은 반환값이 없는 메소드를 참조하는 델리게이트 변수이다.
Func 델리게이트
.Net Framework 에는 총 17가지의 Func 델리게이트가 준비되어있다.
즉, 매개변수가 없는 메소드부터 매개변수가 있는 16개인 메소드까지 총 17개의 메소드를 참조 가능하다는 말이다.
(무명 메소드 뿐만 아니라 일반 메소드도 참조 가능하다)
이정도면 특별한 경우가 아니고서야 별도의 델리게이트를 만들어 쓸 필요가 없겠다.
Func 델리게이트 변수를 선언하는 방법은 다음과 같다.
//매개변수는 없고, 반환값은 float형 Func<float> func0 = () => 0.1f; //int형 매개변수를 1개 가지고 반환값은 float형 Func<int,float> func1 = (a) => a * 0.1f; //int형 매개변수를 2개 가지고 반환값은 float형 Func<int,int,float> func2 = (a,b) => (a+b) * 0.1f; //int형 매개변수를 3개를 가지고 반환값은 float형 Func<int,int,int,float> func3; func3 = (a,b,c) => (a+b+c) * 0.1f; //int형 매개변수가 4개를 가지고 반환값은 float형 Func<int,int,int,int,float> func4; func4 = (a,b,c,d) => (a+b+c+d) * 0.1f;
매개변수와 반환값을 구분하기 위해 int형과 float형으로 나누었다.
보시다시피 매개변수는 앞에서 지정하고, 반환값은 맨뒤에 지정하는것을 알수 있다.
(Func 반환값을 가진 메소드를 참조하는 델리게이트이기 때문에 반환형을 반드시 지정해주거야 한다.)
위와 같이 Func 델리게이트로 메소드를 참조하면 전처럼 델리게이트 타입을 선언하는 과정이 불필요해지므로 아주 간경하게 코드를 작성할수 있다.
그럼 이제 다음 예제를 작성해보자.
namespace func_Test { class MainApp { static float temp(int a, int b, int c) { return(a + b + c) * 0.1 f; } static void Main(string[] args) { Func < float > func0 = () => 0.1 f; Func < int, float > func1 = (a) => a * 0.1 f; Func < int, int, float > func2 = (a, b) => (a + b) * 0.1 f; Func < int, int, int, float > func3; func3 = new Func<int, int, int, float>(temp); // 일반 메소드 참조 Console.WriteLine("func0 반환값: {0}", func0()); Console.WriteLine("func1 반환값: {0}", func1(10)); Console.WriteLine("func2 반환값: {0}", func2(10, 10)); Console.WriteLine("func3 반환값: {0}", func3(10, 10, 10)); } } }
Action 델리게이트
Action 델리게이트는 Func와 똑같다. 다만 참조하는 메소드는 반환값이 없을 분이다.
//매개변수 없음 Action act0 = () => Console.WriteLine("매개변수 없음"); //string 매개변수 1개 Action<string> act1 = (name) => Console.WriteLine(name); //string 매개변수 2개 Action<string,string> act2; act2 = (name,age) => Console.WriteLine(name + " " + age); //int 매개변수 3개 int sum = 0; Action<int,int,int> act3 = (a,b,c) => sum = a + b + c;
반환값이 없는것 빼고는 Func와 같습니다.
바로 예제를 작성해 보겠습니다.
namespace action_Test { class MainApp { static void temp(string name) { Console.WriteLine("name: {0}", name); } static void Main(string[] args) { int sum = 0; Action act0 = () => Console.WriteLine("name: act0"); Action < string > act1 = new Action<string>(temp); // 일반 메소드 참조 Action < string, string > act2 = (name, age) => { Console.WriteLine("name: {0}", name); Console.WriteLine("age: {0}", age); }; Action < int, int, int > act3 = (a, b, c) => sum = a + b + c; act0(); act1("act1"); act2("act2", "35"); act3(1, 2, 3); Console.WriteLine("sum: {0}", sum); } } }