C# 위임
C#의 대리자는 C 또는 C++의 함수에 대한 포인터와 유사합니다. Delegate는 메소드에 대한 참조를 보유하는 참조 유형 변수입니다. 참조는 런타임 시 변경될 수 있습니다.
Delegate는 특히 이벤트 및 콜백 메서드를 구현하는 데 사용됩니다. 모든 대리자(Delegate)는 System.Delegate 클래스에서 파생됩니다.
델리게이트 선언(Delegate)
델리게이트 선언은 델리게이트가 참조할 수 있는 메서드를 결정합니다. 대리자는 동일한 레이블이 있는 메서드를 가리킬 수 있습니다.
예를 들어 대리자가 있다고 가정해 보겠습니다.
public delegate int MyDelegate (string s);
위 대리자는 단일 string 매개변수를 사용하고 int 유형 변수를 반환하는 모든 메서드를 참조하는 데 사용할 수 있습니다.
대리자를 선언하는 구문은 다음과 같습니다.
delegate <return type> <delegate-name> <parameter list>
대리자 인스턴스화(Delegate)
대리자 유형이 선언되면 new 키워드를 사용하여 대리자 개체를 생성해야 하며 특정 메서드와 관련됩니다. 대리자를 생성할 때 new 문에 전달된 매개 변수는 메서드 호출과 동일하게 작성되지만 매개 변수는 없습니다. 예:
public delegate void printString(string s); ... printString ps1 = new printString(WriteToScreen); printString ps2 = new printString(WriteToFile);
다음 예제에서는 정수 매개 변수를 사용하고 정수 값을 반환하는 메서드를 참조하는 데 사용할 수 있는 대리자의 선언, 인스턴스화 및 사용을 보여줍니다.
using System; delegate int NumberChanger(int n); namespace DelegateAppl { class TestDelegate { static int num = 10; public static int AddNum(int p) { num += p; return num; } public static int MultNum(int q) { num *= q; return num; } public static int getNum() { return num; } static void Main(string[] args) { // 创建委托实例 NumberChanger nc1 = new NumberChanger(AddNum); NumberChanger nc2 = new NumberChanger(MultNum); // 使用委托对象调用方法 nc1(25); Console.WriteLine("Value of Num: {0}", getNum()); nc2(5); Console.WriteLine("Value of Num: {0}", getNum()); Console.ReadKey(); } } }
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.
Value of Num: 35 Value of Num: 175
Delegate의 멀티캐스팅
Delegate 개체는 "+" 연산자를 사용하여 결합할 수 있습니다. 병합된 대리자는 병합된 두 대리자를 호출합니다. 동일한 유형의 대리인만 병합할 수 있습니다. "-" 연산자를 사용하면 병합된 대리자에서 구성 요소 대리자를 제거할 수 있습니다.
델리게이트의 이 유용한 기능을 사용하면 델리게이트가 호출될 때 호출될 메서드의 호출 목록을 만들 수 있습니다. 이를 위임된 멀티캐스팅이라고 하며 멀티캐스트라고도 합니다. 다음 프로그램은 대리자의 멀티캐스팅을 보여줍니다.
using System; delegate int NumberChanger(int n); namespace DelegateAppl { class TestDelegate { static int num = 10; public static int AddNum(int p) { num += p; return num; } public static int MultNum(int q) { num *= q; return num; } public static int getNum() { return num; } static void Main(string[] args) { // 创建委托实例 NumberChanger nc; NumberChanger nc1 = new NumberChanger(AddNum); NumberChanger nc2 = new NumberChanger(MultNum); nc = nc1; nc += nc2; // 调用多播 nc(5); Console.WriteLine("Value of Num: {0}", getNum()); Console.ReadKey(); } } }
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.
Value of Num: 75
Purpose of Delegate
다음 예에서는 대리자의 사용을 보여줍니다. printString 대리자는 문자열을 입력으로 사용하고 아무것도 반환하지 않는 메서드를 참조하는 데 사용할 수 있습니다.
이 대리자를 사용하여 두 가지 메서드를 호출합니다. 첫 번째 메서드는 문자열을 콘솔에 인쇄하고 두 번째 메서드는 문자열을 파일에 인쇄합니다.
using System; using System.IO; namespace DelegateAppl { class PrintString { static FileStream fs; static StreamWriter sw; // 委托声明 public delegate void printString(string s); // 该方法打印到控制台 public static void WriteToScreen(string str) { Console.WriteLine("The String is: {0}", str); } // 该方法打印到文件 public static void WriteToFile(string s) { fs = new FileStream("c:\message.txt", FileMode.Append, FileAccess.Write); sw = new StreamWriter(fs); sw.WriteLine(s); sw.Flush(); sw.Close(); fs.Close(); } // 该方法把委托作为参数,并使用它调用方法 public static void sendString(printString ps) { ps("Hello World"); } static void Main(string[] args) { printString ps1 = new printString(WriteToScreen); printString ps2 = new printString(WriteToFile); sendString(ps1); sendString(ps2); Console.ReadKey(); } } }
위 코드를 컴파일하고 실행하면 다음 결과가 생성됩니다.
The String is: Hello World