C 프로그래머라면 대리자를 함수에 대한 포인터로 생각할 수 있습니다. 그러나 C#의 대리자는 단순한 함수 포인터 그 이상입니다. 이 문서에서는 대리인의 개념과 일상적인 프로그래밍에서 대리자를 사용하는 방법을 설명합니다.
기본적으로 대리자는 간접적인 수준을 제공합니다. 유형이 안전한 방식으로 전달되고 실행될 수 있는 코드 조각을 캡슐화합니다. 동작을 즉시 실행하는 대신 개체에 포함됩니다. 해당 개체에 대해 여러 작업을 수행할 수 있으며 그 중 하나는 포함된 동작을 실행하는 것입니다.
대리자를 사용하면 고차 함수, 즉 매개변수로 함수를 받거나 반환 값으로 함수를 반환할 수 있는 함수를 작성할 수 있습니다. 대리자 형식은 대리자가 나타낼 수 있는 메서드 서명, 특히 메서드의 반환 형식 및 해당 매개 변수 형식을 정의합니다. 다음 예제에서 Transformer는 정수를 받아들이고 반환하는 모든 메서드를 나타낼 수 있는 대리자입니다.
delegate int Transformer(int x);
서명을 수행하는 Transformer의 인스턴스에 모든 메서드(람다, 인스턴스 또는 정적 메서드 포함)를 할당할 수 있습니다. 예를 들어 -
Transformer square = x => x * x; Transformer cube = x => x * x * x; Console.WriteLine(square(3)); // prints 9 Console.WriteLine(cube(5)); // prints 125
대리인을 언제 사용해야 하나요?
대리자는 일반적으로 일부 작업을 실행하려는 코드가 해당 작업이 무엇인지에 대한 세부 정보를 알지 못하지만 해당 작업의 인터페이스를 알고 있을 때 사용됩니다.
프로그래밍에서 우리는 종종 특정 작업을 실행해야 하는 상황에 직면하지만 이를 실행하기 위해 어떤 메서드를 호출할지 미리 알지 못합니다. 대리자는 해당 동작을 대리자로 대체한 다음 컨텍스트 및 상황에 필요한 적절한 동작으로 해당 대리자의 구체적인 인스턴스를 전달하여 이 문제를 해결하는 데 도움이 됩니다.
대리인이 무엇이든 하려면 다음 4가지 일이 발생해야 합니다. -
1) 대리자 유형을 선언해야 합니다.
대리자 유형은 본질적으로 그것이 나타내는 함수의 정의입니다. 즉, 함수가 수락할 매개변수 유형과 반환하는 반환 유형으로 구성됩니다.
예를 들어 두 개의 숫자를 입력으로 받아 숫자를 반환하는 메서드를 나타내는 대리자 유형은 −
로 선언할 수 있습니다.delegate int Processor(int numOne, int numTwo);
프로세서는 클래스에 의해 생성된 유형과 유사한 유형입니다. 이 유형의 인스턴스를 만들려면 두 개의 숫자를 입력으로 받아 bool을 반환하는 메서드가 필요합니다.
2) 실행할 코드는 반드시 메소드에 포함되어야 합니다.
위의 대리자 형식과 정확히 동일한 서명을 갖고 런타임 시 상황에 따라 원하는 작업을 수행하는 메서드를 정의합니다. 예를 들어, 다음 방법 중 하나를 사용하여 프로세서 인스턴스를 만들 수 있습니다. 모두 두 개의 숫자를 사용하고 숫자를 반환하기 때문입니다.
static int Add(int numOne, int numTwo){ Return numOne + numTwo; } static int Subtract(int numOne, int numTwo){ Return numOne - numTwo; }
3) 대리자 인스턴스를 생성해야 합니다.
이제 대리자 형식과 올바른 서명이 있는 메서드가 있으므로 해당 대리자 형식의 인스턴스를 만들 수 있습니다. 이 작업을 수행할 때 우리는 본질적으로 대리자 인스턴스가 호출될 때 이 메서드를 실행하도록 C# 컴파일러에 지시합니다.
Processor processorOne = new Processor(Add); Processor processorTwo = new Processor(Subtract);
위의 예제에서는 Add 및 Subtract 메서드가 대리자의 인스턴스를 만드는 동일한 클래스에 정의되어 있다고 가정합니다. 메서드가 다른 클래스에 정의되어 있으면 해당 클래스의 인스턴스가 필요합니다.
4) 대리자 인스턴스를 호출해야 합니다.
이것은 Invoke라는 이름의 대리자 인스턴스에서 메서드를 호출하기만 하면 됩니다. 대리자 인스턴스의 이 메서드에는 대리자 형식 선언이 지정하는 것과 동일한 매개 변수 및 반환 형식 목록이 있습니다. Invoke를 호출하면 대리자 인스턴스의 작업이 실행됩니다.
int sum = processorOne.Invoke(3, 5);
그러나 C#을 사용하면 훨씬 쉽습니다. 대리자 인스턴스가 그 자체로 메서드인 것처럼 직접 호출할 수 있습니다. 예를 들어,
int difference = processorTwo(10, 6);
대리인 결합 및 제거
대리자 인스턴스의 단일 호출로 다른 작업 목록을 실행하려는 경우 C#을 사용하면 그렇게 할 수 있습니다. 시스템. 대리자 유형에는 결합 및 제거라는 두 가지 정적 메서드가 있습니다.
1. 결합
매개 변수로 전달된 대리자의 호출 목록을 연결하는 호출 목록을 사용하여 새 대리자를 만듭니다. 새 대리자 인스턴스가 호출되면 모든 작업이 순서대로 실행됩니다.
public static Delegate Combine(params Delegate[] delegates); // OR public static Delegate Combine(Delegate a, Delegate b);
호출 목록의 작업 중 하나에서 예외가 발생하면 후속 작업이 실행되지 않습니다.
2. 제거
다른 대리자의 호출 목록에서 대리자의 호출 목록의 마지막 항목을 제거합니다. 소스의 호출 목록을 가져오고 값의 호출 목록의 마지막 항목을 제거하여 형성된 호출 목록과 함께 새 대리자를 반환합니다.
public static Delegate Remove(Delegate source, Delegate value);
요약
-
대리자는 단일 메서드 인터페이스와 유사한 특정 유형 및 매개변수 집합으로 동작을 캡슐화합니다.
-
대리자 유형 선언에 의해 설명된 유형 서명은 대리자 인스턴스와 호출 서명을 만드는 데 사용할 수 있는 메서드를 결정합니다.
-
대리자 인스턴스를 생성하려면 대리자가 호출될 때 실행하려는 메서드가 필요합니다.
-
대리자 인스턴스는 문자열과 마찬가지로 변경할 수 없습니다.
-
대리자 인스턴스는 각각 호출 목록(작업 목록)을 포함합니다.
-
대리자 인스턴스는 서로 결합하거나 제거할 수 있습니다.
예시
using System; class Program{ delegate int Transformer(int x); delegate int Processor(int numOne, int numTwo); static void Main(){ Transformer square = x => x * x; Transformer cube = x => x * x * x; Console.WriteLine(square(3)); // prints 9 Console.WriteLine(cube(5)); // prints 125 Processor processorOne = new Processor(Add); Processor processorTwo = new Processor(Subtract); int sum = processorOne.Invoke(3, 5); Console.WriteLine(sum); // prints 8 int difference = processorTwo(10, 6); Console.WriteLine(difference); // prints 4 } static int Add(int numOne, int numTwo){ return numOne + numTwo; } static int Subtract(int numOne, int numTwo){ return numOne - numTwo; } }
출력
9 125 8 4