C#에서는 대리자와 이벤트가 많이 사용됩니다. 특히 양식 프로그래밍을 수행할 때 대리자와 이벤트를 통해 많은 작업을 처리하고 전달해야 합니다. 코드를 작성할 때 좀 더 명확하게 이해할 수 있도록 델리게이트와 이벤트의 사용법과 이유에 대해 자세히 설명합니다.
위임의 사용
이벤트는 메커니즘이고 이벤트는 위임을 통해 구현됩니다. 따라서 위임을 이해하면 이벤트를 더 잘 이해할 수 있습니다. 아래에서 작은 예를 살펴보겠습니다.
이것은 다양한 언어로 프로그래머를 설명하는 코드입니다.
예를 들어 C#을 사용하여 프로그래머를 설명하는 경우, 여기서 programerName 매개변수는 프로그래머의 이름을 나타냅니다.
public void CsharpProgramer(string programerName) { Console.WriteLine(string.Format("{0} 使用C#编程!", programerName)); }
Java를 사용하면
public void JavaProgramer(string programerName) { Console.WriteLine(string.Format("{0} 使用Java语言编程!")); }
언어가 이렇게나 많은데, 이 사람이 누구 프로그래머인지 어떻게 알 수 있을까요? 열거형을 사용하여
public enum ProgramLanguage { CSharp, C, Java }
를 표현한 다음 완전한 설명을 제공합니다. 코드는 다음과 같습니다.
public class ProgramerDescription { //01 public void CsharpProgramer(string programerName) { Console.WriteLine(string.Format("{0} 使用C#编程!", programerName)); } public void CProgramer(string programerName) { Console.WriteLine(string.Format("{0}使用C语言编程!", programerName)); } public void JavaProgramer(string programerName) { Console.WriteLine(string.Format("{0} 使用Java语言编程!")); } //02 public void Description(string programerName, ProgramLanguage type) { switch (type) { case ProgramLanguage.CSharp: CsharpProgramer(programerName); break; case ProgramLanguage.C: CProgramer(programerName); break; case ProgramLanguage.Java: JavaProgramer(programerName); break; default: Console.WriteLine("A kind of new Language that you never heard of."); break; } } } public enum ProgramLanguage { CSharp, C, Java }
호출:
ProgramerDescription pm = new ProgramerDescription(); pm.Description("杨友山", ProgramLanguage.CSharp);
이때 출력은 "Yang Youshan이 사용합니다. C#으로 프로그래밍하기!";
이렇게 하면 프로그래머가 설명하는 간단한 구현이 일단 완성됩니다. 여기서 Description 메서드는 열거 유형을 사용하여 다양한 언어를 구별합니다. 이런 식으로 프로그래밍 언어(C++, PHP 등)가 많기 때문에 유지 관리성이 상대적으로 좋지 않습니다. 언어를 추가하려면 해당 메서드를 추가한 다음 수정해야 합니다. ProgramLanguage 열거 유형입니다. 메서드를 추가하면 부분 클래스를 사용하여 구현할 수 있으므로 원본 프로그램에 거의 영향을 미치지 않지만 열거형을 수정하는 것은 객체 지향 설계의 개방형 및 폐쇄형 원칙에 부합하지 않습니다.
그래서 Description 메서드에서 이를 처리하는 방법, 즉 열거 없이 Description 메서드는 프로그래머에게 설명하기 위해 호출할 메서드(CsharpProgramer, CProgramer, JavaProgramer)를 어떻게 구별합니까?
public void Description(string programerName, 특정 타입의 특정 매개변수)
{
//해당 메소드 호출
}
여기서 특정 타입은 어떤 타입인지 구분하기 위해 사용됩니다. 즉, 내가 호출하고 싶은 메소드를 여기에 매개변수로 직접 전달하는 것이 가장 좋습니다. 예를 들어, C 프로그래머를 설명하기 위해 CProgramer 메소드를 호출하고 싶습니다.
ProgramerDescription pm = new ProgramerDescription() Description(string programerName, 특정 유형 및 a)의 "a 특정 유형 및 특정 매개변수"를 표현하는 방법 특정 매개변수)?
public class ProgramDescriptionDelegate { //委托,表示方法 public delegate void DescriptionDelegate(string programerName); //01 public void CsharpProgramer(string programerName) { Console.WriteLine(string.Format("{0} 使用C#编程!", programerName)); } public void CProgramer(string programerName) { Console.WriteLine(string.Format("{0}使用C语言编程!", programerName)); } public void JavaProgramer(string programerName) { Console.WriteLine(string.Format("{0} 使用Java语言编程!")); } //02 public void Description(string programerName, DescriptionDelegate description) { description(programerName); } }
ProgramDescriptionDelegate pm = new ProgramDescriptionDelegate(); pm.Description("杨友山", pm.CsharpProgramer);결과는 원본 코드와 동일합니다.
위임이란 무엇인가요? MSDN은 이를 다음과 같이 설명합니다. 대리자는 메서드 서명을 정의하는 형식이며, 호환 가능한 서명이 있는 모든 메서드와 연결될 수 있으며 대리자를 통해 호출될 수 있습니다. 대리자는 메서드를 다른 메서드에 매개 변수로 전달하는 데 사용됩니다. 시간 처리기는 대리자를 통해 호출되는 메서드입니다.
대리자
public void Description(string programerName, DescriptionDelegate 설명)을 사용하는 코드를 주의 깊게 살펴보세요. 호출 시
//方法和委托绑定 ProgramDescriptionDelegate pm = new ProgramDescriptionDelegate(); YYS.CSharpStudy.Window.SDelegate.ProgramDescriptionDelegate.DescriptionDelegate csharpDelegate = pm.CsharpProgramer; YYS.CSharpStudy.Window.SDelegate.ProgramDescriptionDelegate.DescriptionDelegate cdelegate = pm.CProgramer; pm.Description("杨友山", csharpDelegate); pm.Description("D.M.Ritchie", cdelegate);
다시 수정:
ProgramDescriptionDelegate pm = new ProgramDescriptionDelegate(); YYS.CSharpStudy.Window.SDelegate.ProgramDescriptionDelegate.DescriptionDelegate pdelegate = null; pdelegate += pm.CsharpProgramer; pdelegate += pm.CProgramer; pm.Description("杨友山", pdelegate);결과:
여기서는 pm.CsharpProgramer가 먼저 실행된 후 pm.CProgramer 메소드가 실행됩니다. 델리게이트는 메소드를 매개변수로 사용할 수 있을 뿐만 아니라 메소드를 바인딩할 수도 있고, 여러 메소드를 바인딩할 수도 있음을 알 수 있습니다.
+=를 사용하여 메서드를 바인딩하고 -=를 사용하여 취소합니다. 위 호출은 다음과 같이 수정할 수 있습니다.ProgramDescriptionDelegate pm = new ProgramDescriptionDelegate(); YYS.CSharpStudy.Window.SDelegate.ProgramDescriptionDelegate.DescriptionDelegate pdelegate = null; pdelegate += pm.CsharpProgramer; pdelegate += pm.CProgramer; pdelegate -= pm.CProgramer; pm.Description("杨友山", pdelegate);