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.IsValue와 x => 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메소드에서 최종 값을 사용할 수 있게 됩니다.