무명 메서드(C# 프로그래밍 가이드)
업데이트: 2007년 11월
2.0보다 이전 버전의 C#에서는 명명된 메서드를 사용하는 방법으로만 대리자를 선언할 수 있었습니다. C# 2.0에는 무명 메서드가 도입되었고 C# 3.0 이상에서는 무명 메서드 대신 람다 식을 사용하여 인라인 코드를 작성하는 방법이 더 선호됩니다. 그러나 이 항목에서 설명하는 무명 메서드에 대한 내용은 람다 식에도 적용됩니다. 무명 메서드에는 람다 식에 없는 기능이 한 가지 있습니다. 무명 메서드를 사용하면 매개 변수 목록을 생략할 수 있으며, 이는 무명 메서드가 여러 시그니처를 가진 대리자로 변환될 수 있음을 의미합니다. 람다 식을 사용해서는 이렇게 할 수 없습니다. 람다 식에 대한 자세한 내용은 람다 식(C# 프로그래밍 가이드)을 참조하십시오.
무명 메서드를 만드는 것은 본질적으로 코드 블록을 대리자 매개 변수로 전달하기 위한 방법입니다. 두 가지 예를 들겠습니다.
// Create a handler for a click event
button1.Click += delegate(System.Object o, System.EventArgs e)
{ System.Windows.Forms.MessageBox.Show("Click!"); };
// Create a delegate instance
delegate void Del(int x);
// Instantiate the delegate using an anonymous method
Del d = delegate(int k) { /* ... */ };
무명 메서드를 사용하면 별도의 메서드를 만들 필요가 없으므로 대리자를 인스턴스화하는 데 따르는 코딩 오버헤드를 줄일 수 있습니다.
예를 들어 메서드를 만드는 것이 불필요한 오버헤드가 되는 상황에서는 대리자 대신 코드 블록을 지정하는 것이 유용합니다. 새로운 스레드를 시작할 때가 좋은 예입니다. 다음 클래스는 스레드를 만들고 스레드에서 실행할 코드도 포함하므로 대리자를 위한 추가 메서드를 만들 필요가 없습니다.
void StartThread()
{
System.Threading.Thread t1 = new System.Threading.Thread
(delegate()
{
System.Console.Write("Hello, ");
System.Console.WriteLine("World!");
});
t1.Start();
}
설명
무명 메서드의 매개 변수 범위는 무명 메서드 블록입니다.
무명 메서드 블록 안에서 블록 밖을 대상으로 goto, break 또는 continue와 같은 점프 문을 사용하면 오류가 발생합니다. 무명 메서드 블록 밖에서 블록 안을 대상으로 goto, break 또는 continue와 같은 점프 문을 사용해도 오류가 발생합니다.
지역 변수 및 매개 변수의 범위에 무명 메서드 선언이 포함되는 경우 이러한 변수를 무명 메서드의 외부 변수라고 합니다. 예를 들어, 다음 코드 단편에서 n은 외부 변수입니다.
int n = 0;
Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n); };
지역 변수와는 달리 캡처된 변수의 수명은 무명 메서드를 참조하는 대리자가 가비지 수집의 대상이 될 때까지 연장됩니다. n에 대한 참조는 대리자가 만들어질 때 캡처됩니다.
무명 메서드에서는 외부 범위의 ref 또는 out 매개 변수에 액세스할 수 없습니다.
무명 메서드 블록에서는 안전한 코드에만 액세스할 수 있습니다.
무명 메서드는 is 연산자의 왼쪽에 사용할 수 없습니다.
예제
다음 예제에서는 대리자를 인스턴스화하는 두 가지 방법을 보여 줍니다.
대리자를 무명 메서드에 연결
대리자를 명명된 메서드(DoWork)에 연결
각각의 경우에서 대리자가 호출되면 메시지가 표시됩니다.
// Declare a delegate
delegate void Printer(string s);
class TestClass
{
static void Main()
{
// Instatiate the delegate type using an anonymous method:
Printer p = delegate(string j)
{
System.Console.WriteLine(j);
};
// Results from the anonymous delegate call:
p("The delegate using the anonymous method is called.");
// The delegate instantiation using a named method "DoWork":
p = new Printer(TestClass.DoWork);
// Results from the old style delegate call:
p("The delegate using the named method is called.");
}
// The method associated with the named delegate:
static void DoWork(string k)
{
System.Console.WriteLine(k);
}
}
/* Output:
The delegate using the anonymous method is called.
The delegate using the named method is called.
*/
참고 항목
개념
참조
안전하지 않은 코드 및 포인터(C# 프로그래밍 가이드)
명명된 메서드와 무명 메서드의 대리자 비교(C# 프로그래밍 가이드)