C# delegate - slog(완료)

C# delegate slog

C#의 delegate에 대해 고찰하고 다양한 사례에 대해서 알아봅니다.

delegate란?

C#의 delegate는 메소드를 참조하는 변수이며, 참조형 변수이기 때문에 null또는 메소드 참조가 담길 수 있으며, 컴파일 타임 때 인자 및 반환 형을 검사합니다.

delegate는 다음 처럼 정의 할 수 있습니다.

delegate 반환형 딜리게이트명(인자1, 인자2, ..);

이 delegate 형에 담길 수 있는 메소드는 인자 타입 일치 및 개수 일치, 반환형 일치이면 어떤 메소드이던 됩니다. 더군다나, 메소드가 정적 메소드이던 인스턴스 메소드이던 상관하지 않으므로 그 활용성이 큽니다.

delegate 활용사례

LINQ - 입력 -> 출력에서 출력의 값 결정

LINQ를 종종 사용하신 분들이라면, 알게 모르게 이미 delegate를 사용중입니다.
delegate형은 값처럼 취급되지만 메소드처럼 원할 때 호출할 수 있습니다.
이게 람다 형식과 잘 결합하여 LINQ에서 사용되고 있습니다. 가령,

var result = list.Where(x => x.IsValid).OrderBy(x => x.Number);

일 때, x => x.IsValuex => x.Number는 람다로 표현되었으며, 람다는 메소드이고, 메소드기 때문에 delegate 형과 타입만 맞다면 사용할 수 있습니다. x => x.IsValid는 형식 유추에 따라서 Func<bool>이고 Func가 delegate이므로 바로 이렇게 쓸 수 있게 됩니다.
마찬가지로 x => x.Number가 형식유추에 의해서 Func<int>가 됩니다.
재미있는 것은 이 두 람다가 실행할 수 있는 메소드와 같으므로, 적절히 Where메소드와 OrderBy메소드 내부에서 필요에 따라 호출됩니다. 그러면 내가 필요간 결과 값만 취하는 방식으로, 조회하는 대상이 무엇이든 상관없이 원하는 비교 또는 정렬등을 할 수 있게 됩니다.


변경되는 값 추적

또 수시로 변할 수 있는 값을 원할 때 취하고 싶은데, 메소드 인자로 값을 넘겨버리면 그 값이 결정 되므로 값이 변경될 때마다 Update등이 메소드를 호출해서 변경값을 적용해야 하는데 번거롭습니다.

만약, info.X 값이 종종 변하는 값이라면,
longProcess(info.X)를 하는 대신, longProcess(() => info.X) 를 했을 때 info.X값이 변하는 족족 longProcess메소드에서 최종 값을 사용할 수 있게 됩니다.

3개의 좋아요

코드 실행 파이프라인

delegate형을 사용하면 코드 블럭을 값처럼 사용할 수 있어서 배열 등에 담을 수 있게 됩니다.
즉, 코드의 흐름을 체인의 조합에 따라 동적으로 제어할 수 있게 됩니다.

1개의 좋아요

함수형 언어

함수형 언어에서는 동일한 입력값에 의해 동일한 결과값이 나오도록 하는게 중요합니다. 이런 메소드를 적절히 조합할 수 있다면, 단위검증을 기계적으로 할 수 있으므로, 코드 유지보수 측면에서 장점이 되는것 같습니다.
C#에서는 C# 9.0부터 var func = static (int value) => value + 5;의 형태로 정적 람다를 통해 이를 가능하게 합니다.

1개의 좋아요

Fluent 패턴에 사용

Fluent 패턴 또는 Fluent 인터페이스 패턴을 이용하면 코드상으로 이런 체인을 직관적으로 표현할 수 있습니다. 체인은 런타임 시 생성되지만, Fluent 인터페이스 패턴은 선언적 성질이 있으므로 생성자 등에서 처리되어 이후 대체로 체인이 변하지 않습니다.

1개의 좋아요