다음을 통해 공유


Delegate 클래스

대리자는 정적 메서드 또는 클래스 인스턴스 및 해당 클래스의 인스턴스 메서드를 참조하는 데이터 구조입니다.

네임스페이스: System
어셈블리: mscorlib(mscorlib.dll)

구문

‘선언
<SerializableAttribute> _
<ClassInterfaceAttribute(ClassInterfaceType.AutoDual)> _
<ComVisibleAttribute(True)> _
Public MustInherit Class Delegate
    Implements ICloneable, ISerializable
‘사용 방법
Dim instance As Delegate
[SerializableAttribute] 
[ClassInterfaceAttribute(ClassInterfaceType.AutoDual)] 
[ComVisibleAttribute(true)] 
public abstract class Delegate : ICloneable, ISerializable
[SerializableAttribute] 
[ClassInterfaceAttribute(ClassInterfaceType::AutoDual)] 
[ComVisibleAttribute(true)] 
public ref class Delegate abstract : ICloneable, ISerializable
/** @attribute SerializableAttribute() */ 
/** @attribute ClassInterfaceAttribute(ClassInterfaceType.AutoDual) */ 
/** @attribute ComVisibleAttribute(true) */ 
public abstract class Delegate implements ICloneable, ISerializable
SerializableAttribute 
ClassInterfaceAttribute(ClassInterfaceType.AutoDual) 
ComVisibleAttribute(true) 
public abstract class Delegate implements ICloneable, ISerializable

설명

Delegate 클래스는 대리자 형식의 기본 클래스입니다. 하지만 시스템과 컴파일러만이 Delegate 클래스와 MulticastDelegate 클래스로부터 명시적으로 파생시킬 수 있습니다. 또한 대리자 형식에서 새로운 형식을 파생할 수 없습니다. Delegate 클래스는 대리자 형식으로 간주되지 않으며 대리자 형식을 파생하기 위해 이용되는 클래스입니다.

대부분 언어들은 delegate 키워드를 구현하고 해당 언어의 컴파일러는 또한 MulticastDelegate 클래스에서 파생 시킬 수 있습니다. 그러므로 사용자는 언어에서 제공하는 delegate 키워드를 사용해야 합니다.

대리자 형식을 선언하면 하나 이상의 메서드의 시그니처를 지정하는 계약 파일을 만듭니다. 대리자는 다음에 대한 참조가 있는 대리자 형식의 인스턴스입니다.

  • 형식의 인스턴스 메서드와 해당 형식에 할당할 수 있는 대상 개체

  • 숨겨진 this 매개 변수가 형식 매개 변수 목록에서 노출되는, 형식의 인스턴스 메서드. 해당 대리자를 열린 인스턴스 대리자라고 합니다.

  • 정적 메서드

  • 정적 메서드와 해당 메서드의 첫 번째 매개 변수에 할당할 수 있는 대상 개체. 해당 대리자를 첫 번째 인수에 대해 닫혀 있다고 합니다.

대리자 바인딩에 대한 자세한 내용은 공용 형식 시스템의 대리자CreateDelegate(Type,Object,MethodInfo,Boolean)를 참조하십시오.

참고

.NET Framework 버전 1.0 및 1.1에서 대리자는 메서드의 시그니처가 대리자 형식에 의해 지정된 시그니처와 정확하게 일치할 때만 메서드를 나타낼 수 있습니다. 따라서 위 목록의 첫 번째 및 세 번째 항목이 지원되며, 첫 번째 항목의 경우 형식이 정확하게 일치해야 합니다.

대리자가 첫 번째 인수에 대해 닫혀 있는 인스턴스 메서드를 나타낼 경우(가장 일반적인 경우), 이 대리자는 메서드의 진입점에 대한 참조와 메서드가 정의된 형식에 할당할 수 있는 형식의 개체(대상 개체)에 대한 참조를 저장합니다. 대리자가 열린 인스턴스 메서드를 나타낼 경우, 이 대리자는 메서드의 진입점에 대한 참조를 저장합니다. 대리자 시그니처에는 형식 매개 변수 목록의 숨겨진 this 매개 변수가 포함되어야 합니다. 이 경우 대리자에는 대상 개체에 대한 참조가 없으므로 대리자를 호출할 때 대상 개체를 제공해야 합니다.

대리자가 정적 메서드를 나타낼 경우, 이 대리자는 메서드의 진입점에 대한 참조를 저장합니다. 대리자가 첫 번째 인수에 대해 닫혀 있는 정적 메서드를 나타낼 경우, 이 대리자는 메서드의 진입점에 대한 참조와 메서드의 첫 번째 인수의 형식에 할당할 수 있는 대상 개체에 대한 참조를 저장합니다. 대리자가 호출되면 정적 메서드의 첫 번째 인수가 대상 개체를 받습니다.

대리자의 호출 목록은 정렬된 대리자의 집합이며 목록의 각 요소는 대리자가 나타내는 메서드 중 정확히 하나를 호출합니다. 호출 목록은 중복 메서드를 포함할 수 있습니다. 호출하는 동안 메서드는 호출 목록에 나타난 순서대로 호출됩니다. 대리자는 호출 목록의 모든 메서드를 호출하려고 하며, 중복된 메서드는 호출 목록에 표시될 때마다 호출됩니다. 대리자는 변경할 수 없으며 일단 만들어지면 대리자의 호출 목록은 바뀌지 않습니다.

대리자는 하나 이상의 메서드를 호출할 수 있고 결합하는 연산에 사용될 수 있으므로 멀티캐스트 대리자와 결합할 수 있는 대리자로 분류됩니다.

CombineRemove와 같은 결합하는 연산은 기존의 대리자를 변경하지 않습니다. 대신 그러한 연산은 연산의 결과인 바뀌지 않은 대리자나 Null 참조(Visual Basic의 경우 Nothing)를 포함하는 새로운 대리자를 반환합니다. 연산의 결과가 한 메서드도 참조하지 않는 대리자일 경우 결합하는 연산은 Null 참조(Visual Basic의 경우 Nothing)를 반환합니다. 요청된 연산이 아무 영향이 없으면 결합하는 연산은 바뀌지 않은 대리자를 반환합니다.

호출된 메서드가 예외를 throw하면 메서드는 실행을 멈추고 예외는 대리자의 호출자에게 전달됩니다. 그리고 호출 목록에 남아있는 메서드는 호출되지 않습니다. 호출자 안에서 예외를 catch해도 이 동작은 변하지 않습니다.

대리자에 의해서 호출된 메서드의 시그니처에 반환 값이 포함될 때 대리자는 호출 목록의 마지막 요소의 반환 값을 반환합니다. 시그니처에 참조로 전달되는 매개 변수가 포함될 때, 매개 변수의 마지막 값은 순서대로 실행하고 매개 변수의 값을 업데이트하는 호출 목록의 모든 메서드의 결과입니다.

컴파일러는 대리자에게 BeginInvokeEndInvoke 등의 두 가지 추가 메서드를 제공합니다. 이러한 메서드에 대한 자세한 내용은 동기 메서드를 비동기 방식으로 호출을 참조하십시오.

C 또는 C++에서 대리자와 가장 비슷한 것은 함수 포인터입니다. 대리자는 정적 메서드 또는 인스턴스 메서드를 나타냅니다. 대리자가 인스턴스 메서드를 나타내는 경우 메서드의 진입점뿐만 아니라 클래스 인스턴스에 대한 참조도 저장합니다. 함수 포인터와는 달리 대리자는 개체 지향적이고 형식이 안정적입니다.

예제

다음 예제는 표준 대리자를 정의하는 방법을 보여 줍니다.

Imports System

Public Class SamplesDelegate

   ' Declares a delegate for a method that takes in an int and returns a String.
   Delegate Function myMethodDelegate(myInt As Integer) As [String]

   ' Defines some methods to which the delegate can point.
   Public Class mySampleClass

      ' Defines an instance method.
      Public Function myStringMethod(myInt As Integer) As [String]
         If myInt > 0 Then
            Return "positive"
         End If
         If myInt < 0 Then
            Return "negative"
         End If
         Return "zero"
      End Function 'myStringMethod

      ' Defines a static method.
      Public Shared Function mySignMethod(myInt As Integer) As [String]
         If myInt > 0 Then
            Return "+"
         End If
         If myInt < 0 Then
            Return "-"
         End If
         Return ""
      End Function 'mySignMethod
   End Class 'mySampleClass

   Public Shared Sub Main()

      ' Creates one delegate for each method.
      Dim mySC As New mySampleClass()
      Dim myD1 As New myMethodDelegate(AddressOf mySC.myStringMethod)
      Dim myD2 As New myMethodDelegate(AddressOf mySampleClass.mySignMethod)

      ' Invokes the delegates.
      Console.WriteLine("{0} is {1}; use the sign ""{2}"".", 5, myD1(5), myD2(5))
      Console.WriteLine("{0} is {1}; use the sign ""{2}"".", - 3, myD1(- 3), myD2(- 3))
      Console.WriteLine("{0} is {1}; use the sign ""{2}"".", 0, myD1(0), myD2(0))

   End Sub 'Main

End Class 'SamplesDelegate 


'This code produces the following output:
' 
'5 is positive; use the sign "+".
'-3 is negative; use the sign "-".
'0 is zero; use the sign "".

using System;
public class SamplesDelegate  {

   // Declares a delegate for a method that takes in an int and returns a String.
   public delegate String myMethodDelegate( int myInt );

   // Defines some methods to which the delegate can point.
   public class mySampleClass  {

      // Defines an instance method.
      public String myStringMethod ( int myInt )  {
         if ( myInt > 0 )
            return( "positive" );
         if ( myInt < 0 )
            return( "negative" );
         return ( "zero" );
      }

      // Defines a static method.
      public static String mySignMethod ( int myInt )  {
         if ( myInt > 0 )
            return( "+" );
         if ( myInt < 0 )
            return( "-" );
         return ( "" );
      }
   }

   public static void Main()  {

      // Creates one delegate for each method.
      mySampleClass mySC = new mySampleClass();
      myMethodDelegate myD1 = new myMethodDelegate( mySC.myStringMethod );
      myMethodDelegate myD2 = new myMethodDelegate( mySampleClass.mySignMethod );

      // Invokes the delegates.
      Console.WriteLine( "{0} is {1}; use the sign \"{2}\".", 5, myD1( 5 ), myD2( 5 ) );
      Console.WriteLine( "{0} is {1}; use the sign \"{2}\".", -3, myD1( -3 ), myD2( -3 ) );
      Console.WriteLine( "{0} is {1}; use the sign \"{2}\".", 0, myD1( 0 ), myD2( 0 ) );
   }

}


/*
This code produces the following output:
 
5 is positive; use the sign "+".
-3 is negative; use the sign "-".
0 is zero; use the sign "".
*/ 
using namespace System;
delegate String^ myMethodDelegate( // Declares a delegate for a method that takes in an int and returns a String.
int myInt );

// Defines some methods to which the delegate can point.
ref class mySampleClass
{
public:

   // Defines an instance method.
   String^ myStringMethod( int myInt )
   {
      if ( myInt > 0 )
            return ("positive");

      if ( myInt < 0 )
            return ("negative");

      return ("zero");
   }


   // Defines a static method.
   static String^ mySignMethod( int myInt )
   {
      if ( myInt > 0 )
            return ("+");

      if ( myInt < 0 )
            return ("-");

      return ("");
   }

};

int main()
{
   
   // Creates one delegate for each method.
   mySampleClass^ mySC = gcnew mySampleClass;
   myMethodDelegate^ myD1 = gcnew myMethodDelegate( mySC, &mySampleClass::myStringMethod );
   myMethodDelegate^ myD2 = gcnew myMethodDelegate( mySampleClass::mySignMethod );
   
   // Invokes the delegates.
   Console::WriteLine( "{0} is {1}; use the sign \"{2}\".", 5, myD1( 5 ), myD2( 5 ) );
   Console::WriteLine( "{0} is {1}; use the sign \"{2}\".",  -3, myD1(  -3 ), myD2(  -3 ) );
   Console::WriteLine( "{0} is {1}; use the sign \"{2}\".", 0, myD1( 0 ), myD2( 0 ) );
}

/*
This code produces the following output:

5 is positive; use the sign "+".
-3 is negative; use the sign "-".
0 is zero; use the sign "".
*/
import System.*;

public class SamplesDelegate
{
    /** @delegate 
     */
    // Declares a delegate for a method that takes in an int and returns
    // a String.
    public delegate String MyMethodDelegate(int myInt);

    // Defines some methods to which the delegate can point.
    public static class MySampleClass
    {
        // Defines an instance method.
        public String MyStringMethod(int myInt)
        {
            if (myInt > 0)  {
                return "positive";
            }
            if (myInt < 0) {
                return "negative";
            }
            return "zero";
        } //myStringMethod

        // Defines a static method.
        public static String MySignMethod(int myInt)
        {
            if (myInt > 0) {
                return "+";
            }
            if (myInt < 0) {
                return "-";
            }
            return "";
        } //MySignMethod
    } //MySampleClass

    public static void main(String[] args)
    {
        // Creates one delegate for each method.
        MySampleClass mySC = new MySampleClass();
        MyMethodDelegate myD1 = new MyMethodDelegate(mySC.MyStringMethod);
        MyMethodDelegate myD2 = new MyMethodDelegate(MySampleClass.MySignMethod);
        // Invokes the delegates.
        Console.WriteLine("{0} is {1}; use the sign \"{2}\".", 
            (Int32)(5), System.Convert.ToString(myD1.Invoke(5)), 
            System.Convert.ToString(myD2.Invoke(5)));
        Console.WriteLine("{0} is {1}; use the sign \"{2}\".",
            System.Convert.ToString(-3), System.Convert.ToString(myD1.Invoke(-3)),
            System.Convert.ToString(myD2.Invoke(-3)));
        Console.WriteLine("{0} is {1}; use the sign \"{2}\".", (Int32)(0),
            System.Convert.ToString(myD1.Invoke(0)), System.Convert.ToString(
            myD2.Invoke(0)));
    } //main
} //SamplesDelegate 

/*
This code produces the following output:
 
5 is positive; use the sign "+".
-3 is negative; use the sign "-".
0 is zero; use the sign "".
*/

상속 계층 구조

System.Object
  System.Delegate
     System.MulticastDelegate

스레드로부터의 안전성

이 형식의 모든 public static(Visual Basic의 경우 Shared) 멤버는 스레드로부터 안전합니다. 인터페이스 멤버는 스레드로부터 안전하지 않습니다.

플랫폼

Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

.NET Framework에서 모든 플래폼의 모든 버전을 지원하지는 않습니다. 지원되는 버전의 목록은 시스템 요구 사항을 참조하십시오.

버전 정보

.NET Framework

2.0, 1.1, 1.0에서 지원

.NET Compact Framework

2.0, 1.0에서 지원

참고 항목

참조

Delegate 멤버
System 네임스페이스
MulticastDelegate

기타 리소스

동기 메서드를 비동기 방식으로 호출