프로그래밍/C#

[C#] Action, Func

갓똥 2020. 4. 16. 17:32
728x90
반응형

1. Action

using System;

class Program {
    public static void Foo1(int arg1)           { }
    public static void Foo2(int arg1, int arg2) { }
    
    static void Main() {
        ? f1 = Foo1;
        ? f2 = Foo2;
    }
}

 

Main에서 Foo1, Foo2 메소드의 정보를 담고 싶다.
그렇다면 앞선 내용대로 delegate를 사용하면 된다.

 

using System;

delegate void Foo1(int arg1);
delegate void Foo2(int arg1, int arg2);

class Program {
    public static void Foo1(int arg1)           { }
    public static void Foo2(int arg1, int arg2) { }
    
    static void Main() {
        Foo1 f1 = Foo1;
        Foo2 f2 = Foo2;
    }
}

 

이렇게 하면 되지만 후에 인자를 3개, 4개 혹은 다른 타입의 인자를 받게 되면
그에 대한 delegate를 추가로 계속 만들어 주어야 한다.
이 부분을 보완해서 제너릭을 이용해 아래와 같이 만들 수 있다.

 

using System;

delegate void Action<T>(T arg1);
delegate void Action<T1, T2>(T1 arg1, T2 arg2);

class Program {
    public static void Foo1(int arg1)           { }
    public static void Foo2(int arg1, int arg2) { }
    
    static void Main() {
        Action<int> f1 = Foo1;
        Action<int, int> = Foo2;
    }
}

 

위와 같이 다른 타입을 받는 메소드가 생길 때의 문제는 해결되었다.
하지만 인자가 늘어났을 때에 대한 문제는 해결되지 않았다.
delegate의 이름을 Action으로 했는데 사실 Action은 C#에서 제공하는 delegate이다.
인자가 없는 것부터 인자 1개, 2개, ... 16개까지 쭉 받을 수 있다.

 

using System;

class Program {
    public static void Foo1(int arg1)           { }
    public static void Foo2(int arg1, int arg2) { }
    
    static void Main() {
        Action<int> f1 = Foo1;
        Action<int, int> = Foo2;
    }
}

 

반환값이 void인 메소드는 미리 정의되어 있는 Action을 사용하면 된다.

 


2. Func

using System;

class Program {
    public static int Goo1(int arg1)           { return 0; }
    public static int Goo2(int arg1, int arg2) { return 0; }
    
    static void Main() {
        ? f1 = Goo1;
        ? f2 = Goo2;
    }
}

 

이번에는 반환값이 있는 메소드의 경우이다.
Action과 같이 delegate를 만들어야 한다.
이번엔 이름을 Func라고 하자.

 

using System;

delegate int Func(int arg1);
delegate int Func(int arg1, int arg2);

class Program {
    public static int Goo1(int arg1)           { return 0; }
    public static int Goo2(int arg1, int arg2) { return 0; }
    
    static void Main() {
        Func f1 = Goo1;
        Func f2 = Goo2;
    }
}

 

Action과 같이 다른 타입도 받기 위해 제너릭을 사용하자.

 

using System;

delegate TResult Func<T, TResult>(T arg1);
delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);

class Program {
    public static int Goo1(int arg1)           { return 0; }
    public static int Goo2(int arg1, int arg2) { return 0; }
    
    static void Main() {
        Func<int, int> f1 = Goo1;
        Func<int, int, int> f2 = Goo2;
    }
}

 

마찬가지로 Func역시 C#에서 제공된다.
따라서 따로 delegate를 만들지 않고 사용해도 된다.

 

using System;

class Program {
    public static int Goo1(int arg1)           { return 0; }
    public static int Goo2(int arg1, int arg2) { return 0; }
    
    static void Main() {
        Func<int, int> f1 = Goo1;
        Func<int, int, int> f2 = Goo2;
    }
}

 

반환값이 있는 메소드는 미리 정의되어 있는 Func를 사용하면 된다.

 


3. 정리

① Generic Delegate

728x90
반응형