2009-06-10 5 views
33

위임을 필요로하는 무언가를 한 번만 호출하면 대리인을 정의하고 명명하는 데 지쳐있을 수밖에 없습니다. 예를 들어, 나는 아마도 다른 스레드에서 양식에 때 .refresh()를 호출하고 싶었다, 그래서 나는이 코드를 썼다 : 내가, 내가 충분히 읽을 것을 무서워조차 확실하지 않다C#의 익명 대리자

private void RefreshForm() 
{ 
    if (InvokeRequired) 
     Invoke(new InvokeDelegate(Refresh)); 
    else 
     Refresh(); 
} 

을 그것은 나중에 어떤 단계에서는 작동하지 않을 것입니다.
InvokeDelegate는 실제로 다른 파일에서 선언되지만 실제로는 에 전체 대리인이 필요합니다. 일반 대표는 전혀 없습니까?
예를 들어 펜 클래스가 있지만 펜도 있습니다. pen-of-choice 그래서 모든 것을 다시 만들 필요가 없습니다. 그것은 동일하지는 않지만, 나는 당신이 내 뜻을 이해하기를 바랍니다.

+1

C#에는 "익명 대리자"같은 것이 없습니다. 대리자 (사용중인 것과 같은)와 익명 메서드 (대리자를 통해서만 액세스 할 수 있음)가 있습니다. – Lucas

+3

C# 스펙에서는 "익명 메소드"라는 용어가 올바른 방법 일 것이라고 생각합니다. 그러나이 용어는 많은 사람들이 익명 메서드를 매개 변수로 사용하여 인스턴스화 된 대리자를 의미합니다. 즉, 같은 것을 의미하지만 누군가 다른 용어보다 한 용어를 사용할 수있는 컨텍스트는 종종 대리자 할당이 발생하는지 또는 익명 메소드가 다른 메소드에 직접 전달되는지 여부에 달려 있습니다. 나는 그 반대 주장을 환영한다. –

답변

52

예. .NET 3.5에서는 FuncAction 대리자를 사용할 수 있습니다. Func 대리자는 값을 반환하고 Action 대리자는 void를 반환합니다. 여기 유형 이름은 다음과 같은 형태가 될 것이다 : 그들은 4 개 인수 각각 중단 이유를 모르겠어요

System.Func<TReturn> // (no arg, with return value) 
System.Func<T, TReturn> // (1 arg, with return value) 
System.Func<T1, T2, TReturn> // (2 arg, with return value) 
System.Func<T1, T2, T3, TReturn> // (3 arg, with return value) 
System.Func<T1, T2, T3, T4, TReturn> // (4 arg, with return value) 

System.Action // (no arg, no return value) 
System.Action<T> // (1 arg, no return value) 
System.Action<T1, T2> // (2 arg, no return value) 
System.Action<T1, T2, T3> // (3 arg, no return value) 
System.Action<T1, T2, T3, T4> // (4 arg, no return value) 

하지만 항상 나를 위해 충분했다.

+2

4는 구체적인 규칙은 아니지만 과거에는 매개 변수 조합을 고려해야합니다. –

+1

이전 .NET 코드를 3.5로 이식 할 때 대리자를 볼 때 Func 또는 Action 중 하나를 바꿉니다. – RichardOD

+10

프레임 워크의 다음 버전에는 4 개 이상의 매개 변수에 대한 Func 및 Action이 포함됩니다. –

4

짧은 버전 :

Invoke((MethodInvoker)delegate { Refresh(); }); 

그런 다음 당신은 또한 InvokeRequired의 확인을 삭제할 수 있습니다; 그냥 그대로 부르면됩니다.

private void SetControlText(Control ctl, string text) 
{ 
    Invoke((MethodInvoker)delegate { ctl.Text = text; }); 
} 
+0

왜 기존 대리자 형식으로 캐스팅하기 위해 익명의 대리자를 만들겠습니까? 위임 유형을 직접 사용해야합니다. –

+2

@Brian : 다음과 같은 의미입니다. Invoke (새 MethodInvoker (delegate {ctl.Text = text;}))); ? 내가 볼 수있는 한 위의 코드와 동일한 일리노이 코드를 생성하므로 개인적인 취향에 미치지 못합니다. –

+0

MethodInvoker와 Action의 차이점은 무엇입니까? 또한 InvokeRequired를 검사하는 것이 더 나은 방법 인 것처럼 보입니다 (예 : 더 빠름). – Nefzen

26

사용할 수있는 액션 대리인이있다 : 당신이 매개 변수를 전달해야하는, 그래서 다른 매개 변수 별 명 규모의 필요 (뿐만 아니라 매개 변수가없는 액션 위임와 마찬가지로 잘 작동이)가없는 경우에도 작동 그래서 같은 :

private void RefreshForm() 
{ 
    if (InvokeRequired) Invoke((Action)(() => Refresh())); 
    else Refresh(); 
} 

마지막으로 거기에 익명의 대리인이 구문은 다음과 같습니다 :

람다 구문

private void RefreshForm() 
{ 
    if (InvokeRequired) Invoke(new Action(Refresh)); 
    else Refresh(); 
} 

또는,

private void RefreshForm() 
{ 
    if (InvokeRequired) Invoke((Action)(delegate { Refresh(); })); 
    else Refresh(); 
} 
+2

이상하게도 두 번째 및 세 번째 구문은 대리자 형식이 아니므로 System.Delegate로 변환 할 수 없다는 말은 작동하지 않습니다. 그러나 액션은 내가 원하는 것입니다. – Nefzen

+1

익명 대리자는 형식 대리자가 아니기 때문에이 방법으로 Invoke에 전달할 수 없습니다. 여기서 쓴 것은 컴파일조차하지 않습니다. –

+1

ㅎ, 그건 내가 게시하기 전에 확인하지 않고 얻는 것입니다. 나는 가능한 빨리 해결할 것이다. –

1

예, 일반 대리인이 있습니다. Action<T1, T2...>은 일부 매개 변수를 사용하고 값을 반환하지 않는 일반 대리자이며 Func<T1, T2...R>은 일부 매개 변수를 사용하여 값을 반환하는 일반 대리자입니다.

2

전적으로 위임자 인 이 필요합니까? 거기에 없습니다 모든 일반 대표단?

Intellisense에서 매개 변수 이름을 알 수 있기 때문에 자신의 대리자를 정의하면 실제로 디버깅이 더 쉽게 이루어질 수 있습니다. 예를 들어 당신은 다음과 같이 위임 쓰기 : 당신이 그것을 코드를 사용하는 경우

public delegate int UpdateDelegate(int userID, string city, string, state, string zip); 

는, .NET는 등, 이름을 위임, 매개 변수 이름을 알려 것, 그래서 많은 컨텍스트 바로 대리자 정의 경우에있다 당신은 무언가가 어떻게 사용되는지 정확히 모릅니다.

Func<T> 
Func<T, U> 
Func<T, U, V> 
Func<T, U, V, W> 
Action, Action<T> 
Action<T, U> 
Action<T, U, V> 
Action<T, U, V, W> 

ActionAction가 존재 : 당신이 인텔리을 희생 괜찮다면

그러나, 임시 대의원으로 사용할 수있는 시스템 네임 스페이스에 definined 대표의 클래스는 이미 존재 .NET 2.0이지만이 종류의 기타 특별 기능에 필요한 나머지 대리인과 도우미 클래스를 선언하기에 충분합니다.

8

이 특별한 경우에는 MethodInvoker을 사용하면됩니다. 그 이유는 그것이 존재하는 이유입니다.

if (InvokeRequired) 
    Invoke(new MethodInvoker(Refresh)); 
else 
    Refresh(); 

당신은 뭔가 다른 일을한다면 당신은, 다른 사람이 대답 한로 사용하기 Func을 < T, ... > 또는 작업 < T는 ... > 그들이 사용 사례에 맞게 수 있다면.

+1

이것은 .NET 2.0을위한 최상의 솔루션입니다. –