상세 컨텐츠

본문 제목

[C#] 대리자(Delegate)

.NET/C#

by 클리엘 클리엘 2021. 4. 15. 17:09

본문

728x90

대리자는 어떤 메서드의 참조입니다. 대리자를 호출하면 참조로 저장된 메서드의 주소 값으로 해당 메서드를 호출해 실행합니다.

 

대리자는 다음과 같이 delegate키워드로 선언합니다. 앞에 한정자가 붙거나 생략될 수 있고 뒤에 반환 형식, 대리자 이름, 매개변수가 올 수 있습니다.

delegate int CalMethod(int i, int j);

반환 형식과 매개변수는 대리자로 호출하려는 메서드의 형식에 따릅니다. 예제에서는 다음의 메서드를 구현하였습니다.

public static int Plus(int i, int j)
{
	return i + j;
}

public static int Minus(int i, int j)
{
	return i - j;
}

메서드를 대리자를 통해 호출하려면 위에서 선언한 대리자의 인스턴스를 생성하여 호출합니다.

static void Main(string[] args)
{
	CalMethod calmethod = new CalMethod(Plus);
	int s = calmethod(10, 20);

	Console.WriteLine($"{s}");
}

이미 정해져 있는 메서드 대신 익명 메서드를 구현하여 직접 Delegate에 참조시킬 수도 있습니다. 보통 임시적으로만 특정 기능의 메서드가 필요한 경우 자주 사용되는 방법이기도 합니다.

static void Main(string[] args)
{
	CalMethod calmethod = delegate (int i, int j) {
		return i + j;
	};

	calmethod(10, 20);
}

메서드는 필요한 만큼 대리자에게 여러 개를 연결할 수 있습니다. 이때 대리자를 호출하면 대리자는 연결된 메서드를 순서대로 호출합니다. 이것을 '대리자 체인'이라고 합니다.

static void Main(string[] args)
{
	CalMethod calmethod = new CalMethod(Plus);
	calmethod += new CalMethod(Minus);

	calmethod(20, 10);
}

대리자에 메서드를 연결하기 위해 += 연산자를 사용했는데 반대로 연결을 해제하는 건 -= 연산자를 사용합니다.

calmethod -= new CalMethod(Minus);

참고로 대리자의 연결과 해제는 Delegate의 Combine, Remove메서드를 통해서도 가능합니다.

CalMethod calmethod_plus = new CalMethod(Plus);
CalMethod calmethod_minus = new CalMethod(Minus);

CalMethod calmethod = (CalMethod)Delegate.Combine(calmethod_plus, calmethod_minus);

calmethod(20, 10);

calmethod = (CalMethod)Delegate.Remove(calmethod, calmethod_minus);

calmethod(20, 10);

대리자는 메서드의 형식에 불과합니다. 이 점을 이용하면 메서드 자체를 매개변수로 넘겨 주는 것이 가능합니다.

static void Main(string[] args)
{
	CalMethod calmethod = new CalMethod(Plus);
	AddSum(30, calmethod);
}

public static void AddSum(int x, CalMethod cm)
{
	int r = cm(10, 20);

	Console.WriteLine($"{x + r}");
}

일반적인 메서드와 마찬가지로 대리자 또한 일반화를 통한 구현이 가능합니다.

delegate int CalMethod<T>(T i, T j);

class HelloWorld
{
	public static int Plus<T>(T i, T j)
	{
		dynamic x = i;
		dynamic y = j;

		return x + y;
	}

	public static int Minus(int i, int j)
	{
		return i - j;
	}

	static void Main(string[] args)
	{
		CalMethod<int> calmethod = new CalMethod<int>(Plus);
		AddSum<int>(30, calmethod);
	}

	public static void AddSum<T>(T x, CalMethod<int> cm)
	{
		int r = cm(10, 20);

		dynamic y = x;

		Console.WriteLine($"{y + r}");
	}
}

 

728x90

'.NET > C#' 카테고리의 다른 글

[C#] LINQ  (0) 2021.04.22
[C#] 리플렉션  (0) 2021.04.19
[C#] 대리자(Delegate)  (0) 2021.04.15
[C#] 이벤트(Event)  (0) 2021.04.12
[C#] 람다식  (0) 2021.04.06
[C#] 예외처리  (0) 2021.02.25

태그

관련글 더보기

댓글 영역