본문 바로가기
책/Effective C#

Effective C# - Item7 델리게이트를 이용하여 콜백을 표현하라

by 코딩하는 돼징 2023. 11. 22.
반응형

콜백(Callback)

동기적인 상황에서 어떤 이벤트나 작업의 완료를 알리거나 처리 결과를 전달하는 방식으로 사용된다. C#에서 콜백은 대부분 델리게이트(delegate)를 사용하여 구현된다. 델리게이트는 메서드에 대한 형식 안전한 참조를 제공하며, 비동기적인 상황에서 콜백을 수행하기 위해 이를 활용할 수 있다.


델리게이트(Delegate)

 

C# 문법 - Delegate(대리자)

1. Delegate 형식은 형식인데, 함수 자체를 넘겨주는 그런 형식! callback 형식 함수 자체를 인자로 넘겨주고 함수를 호출한다. 예시) 사장님(Function)의 비서(Delegate)에게 연락을 요청하지만 받지 않아

code-piggy.tistory.com


콜백과 델리게이트는 C#이 제공하는 관용구의 하나이며 람다 표현식을 사용하는 경우에도 널리 활용된다.

.NET Framework라이브러리는 Predicate<T>, Action<T>, Func<T>와 같은 형태로 자주 사용되는 델리게이트를 정의해두고 있다. 

01 Predicate<T>

참/거짓을 반환하는 메서드이다. 주로 컬렉션의 요소를 검사하는데 사용된다.

List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
Predicate<int> isEven = n => n % 2 == 0;
int evenNumber = numbers.Find(isEven);
Console.WriteLine($"Even Number: {evenNumber}"); // Even Number:2 출력

02 Action<T>

매개변수가 하나인 메서들르 나타낸다. 반환값이 없는 경우에 사용된다.

List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
Action<int> printNumber = n => Console.WriteLine(n);
numbers.ForEach(printNumber); // 1 2 3 4 5 출력

03 Func<T,TResult>

Func<T, TResult> 매개변수가 하나인 메서드를 나타낸다. T를 받아들이고 TResult를 반환하는 메서드를 참조할 수 있는 델리게이트이다.

List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
Func<int, bool> isGreaterThanThree = n => n > 3;
bool allGreaterThanThree = numbers.TrueForAll(isGreaterThanThree)
Console.WriteLine($"{allGreaterThanThree}"); // False 출력

List<T>는 콜백을 사용하는 다양한 메서드 

List<int> numbers = Enumerable.Range(1,200).ToList();

var oddNumbers = numbers.Find( n => n % 2 == 1);
var test = numbers.TrueForAll(n => n < 50 );

numbers.RemoveAll(n => n % 2 == 0 );

numbers.ForEach(item => Console.WriteLine(item));

01 Find()

Predicate<int>형식의 델리게이트를 사용하여 리스트 내에 포함된 요소에대하여 테스트를 수행한다. Find()메서드는 이 콜백을 사용하여 각 항목을 테스트하며, 테스트를 통과한 항목만 반환한다.

02 TrueForAll()

각 요소를 개별적으로 테스트하되 모든 항목이 테스트를 통과한 경우에만 true를 반환한다.

03 RemoveAll()

델리게이트에서 정의한 테스트를 통과한 항목들을 리스트에서 제거한다.

04 Foreach()

리스트 내의 각 요소에 대하여 델리게이트로 지정한 동작을 수행한다. 컴파일러는 람다 표현식을 메서드로 변환한 후 이 메서드를 참조하는 델리게이트를 생성한다.


멀티캐스트(multicast) 델리게이트

델리게이트는 여러 개의 메서드를 동시에 호출할 수 있다. 멀티캐스트 델리게이트를 사용하면 하나의 델리게이트 객체가 여러 메서드를 참조할 수 있다. 델리게이트를 호출하면 참조된 모든 메서드가 순서대로 호출된다.

using System;

class Program
{
    delegate void MyPiggy();

    static void Main()
    {
        MyPiggy mypiggy = Piggy1;
        mypiggy += Piggy2;

        // 멀티캐스트 델리게이트 호출
        mypiggy();
    }

    static void Piggy1()
    {
        Console.WriteLine("Piggy1");
    }

    static void Piggy2()
    {
        Console.WriteLine("Piggy2");
    }
}

예외 처리

멀티캐스트 델리게이트를 사용할 때 주의해야 할 점은 하나의 메서드에서 예외가 발생하면 그 즉시 예외 처리가 이루어지며 남은 메서드들은 실행되지 않는다. 그러므 예외가 발생하면 멀티캐스트 델리게이트의 나머지 부분은 실행되지 않게 된다.

using System;

class Program
{
    delegate void MyPiggy();

    static void Main()
    {
        MyPiggy myPiggy = Piggy1;
        myPiggy += MethodWithException;

        // 멀티캐스트 델리게이트 호출
        myPiggy();
    }

    static void Piggy1()
    {
        Console.WriteLine("Piggy1");
    }

    static void MethodWithException()
    {
        Console.WriteLine("MethodWithException");
        throw new Exception("Exception in MethodWithException");
    }
}

결론

델리게이트는 런탐이에 콜백을 구성하는 최고의 방법이다. 델리게이트를 사용하면 콜백을 사용해야 하는 클라이언트를 더욱 단순하게 구성할 수 있을 뿐 아니라 런타임에 콜백 함수를 구성할 수 있다. 게다가 하나의 델리게이트에 여러 개의 콜백함수를 추가할 수 있다.

 

 

 

본 게시글은 Effective C#을 읽고 정리하였습니다.

 

반응형

댓글