2008-09-12 6 views
21

이 대리자를 변환합니다. 나는하려면 다음을 입수했습니다 :내가 모든 익명의 기능에 새로운 오전 도움이 필요 익명 메서드 또는 람다

public void FakeSaveWithMessage(Transaction t) 
{ 
    t.Message = "I drink goats blood"; 
} 

public delegate void FakeSave(Transaction t); 

public void SampleTestFunction() 
{ 
    Expect.Call(delegate { _dao.Save(t); }).Do(new FakeSave(FakeSaveWithMessage)); 
} 

을하지만이 완전히 못생긴이고 나는 가능한 경우 익명 메소드 또는 람다 될 수있는 마십시오의 내부를하고 싶습니다.

Expect.Call(delegate { _dao.Save(t); }).Do(delegate(Transaction t2) { t2.Message = "I drink goats blood"; }); 

Expect.Call(delegate { _dao.Save(t); }).Do(delegate { t.Message = "I drink goats blood"; }); 

을하지만이 나에게

그것이 대리자 형식이 아니기 때문에 'System.Delegate'를 입력하는 익명 메소드를 변환 할 수 없습니다 ** 컴파일 오류를 준다 : 나는 시도 . 내가 잘못 뭐하는 거지

? 때문에 마크 잉그램은 무엇을 게시의


, 아무도 명시 적으로 말했다 비록,이 작업을 수행하는 것입니다, 최선의 대답처럼 보인다 :

public delegate void FakeSave(Transaction t); 

Expect.Call(delegate { _dao.Save(t); }).Do(new FakeSave(delegate(Transaction t2) { t.Message = expected_msg; })); 

답변

27

. 자세한 내용은 아래 링크를 확인하십시오.

http://staceyw1.wordpress.com/2007/12/22/they-are-anonymous-methods-not-anonymous-delegates/

은 기본적으로 당신은 당신의 익명의 대리인 (귀하의 람다 식)의 앞에 캐스트를 넣어해야합니다.

는 경우 링크가 지금 여기에, 아래로 간다 게시물의 복사본입니다 :

그들은 익명 메소드하지 익명 대표입니다.
그것은 우리가 어려울 할 때문에 그냥 이야기 점없는 staceyw1

12 월 (22) 2007 게시 됨. 정확하게 에 대한 이유를 설명하는 데 도움이됩니다. 분명히하기 위해, * 익명의 위임과 같은 것은 없다. 그들은 이 (아직) 존재하지 않습니다. 그들은 "익명 방법"- 마침표입니다. 그것은 우리가 약 을 이야기하는 방법을 우리가 생각하는 방법에 문제. 익명 메소드 선언문 "delegate() {...}"을 살펴 보겠습니다. 이것은 실제로 두 가지 다른 작업이며, 우리가 이것을 과 같이 생각하면 다시는 결코 혼동하지 않을 것입니다. . 컴파일러 의 첫 번째 작업은 유추 된 대리자 서명을 사용하여 커버 아래에있는 익명 메서드를 메서드 서명으로 만듭니다. 에는 이름이 있고 컴파일러에 이 지정되어 있기 때문에 메서드가 "이름이 없음"이라고 말하는 것이 맞지 않습니다. 정상보기에서 그냥 숨겨져 있습니다. 다음으로 수행 할 작업은 메서드를 래핑하는 데 필요한 필수 형식의 대리자 개체를 만드는 것입니다. 이 을 위임자 추론이라고하며 을이 혼동의 원인이 될 수 있습니다. 이 작동하려면 컴파일러가 대리자 형식을 만들 수 있는지 (즉 추측 할 수 있는지) 이어야합니다. 그것은 알려진 구체적인 유형이 있습니다. 이 왜 코드를 작성하는지 알려줍니다.

private void MyMethod() 
{ 
} 

컴파일하지 않습니다 다음 컴파일러는 어떤 위임 유형을 추론 할 수 없기 때문에

1) Delegate d = delegate() { };      // Cannot convert anonymous method to type ‘System.Delegate’ because it is not a delegate type 
2) Delegate d2 = MyMethod;       // Cannot convert method group ‘MyMethod’ to non-delegate type ‘System.Delegate’ 
3) Delegate d3 = (WaitCallback)MyMethod; // No overload for ‘MyMethod’ matches delegate ‘System.Threading.WaitCallback’ 

1 호선은 컴파일되지 않습니다. 컴파일러가 볼 수있는 대리자 유형이 구체적으로 표시되지는 않지만 서명 을 분명히 볼 수 있습니다. 익명 형식의 형식 대리자를 만들 수 있지만 처럼 작동하지 않습니다. 2 번째 줄은 비슷한 이유로 이 컴파일되지 않습니다. 컴파일러는 방법 서명을 알고도 불구하고, 우리는 그것을 대리자 형식을 제공하지 않으며 단지 ( 가있을 수있는 어떤 부작용이되지 않음) 일 일어날 것 하나를 선택하는 을하려고하지 않습니다. 서명과 의도적으로 일치하지 않는 대리인 (WaitCallback 테이크 및 개체)을 사용했기 때문에 3 호선이 작동하지 않습니다.

컴파일 : 대조적으로

4) Delegate d4 = (MethodInvoker)MyMethod; // Works because we cast to a delegate type of the same signature. 
5) Delegate d5 = (Action)delegate { };    // Works for same reason as d4. 
6) Action d6 = MyMethod;        // Delegate inference at work here. New Action delegate is created and assigned. 

이 작동합니다. 줄 1은 을 사용하기 때문에 우리는 컴파일러에게 델리게이트 형식을 사용할 것을 말하고 일치하면 이되므로 작동합니다. 5 호선은 같은 이유로 에서 작동합니다. 우리는 괄호없이 특별한 "대리인"형식을 사용했습니다. 컴파일러는 캐스팅의 메서드를 유추하고 추측 된 위임 자도 형식 인 서명을 사용하여 익명 메서드를 만듭니다. Line 6은 MyMethod()와 Action이 동일한 서명을 사용하기 때문에 작동합니다.

이 정보가 도움이되기를 바랍니다.

항목 : http://msdn.microsoft.com/msdnmag/issues/04/05/C20/

+1

좋은 링크를하지만 (이 람다 구문을 사용하는 것처럼) 난 아직도 왜 * 컴파일러가 자동적으로 캐스팅하지 않습니다 * 이해가 안 돼요 –

+0

링크가 끊어졌습니다. –

+0

아직도 나를 위해 일하고 있습니까? –

0

같은 시도 :

Expect.Call(delegate { _dao.Save(t); }).Do(new EventHandler(delegate(Transaction t2) { t2.CheckInInfo.CheckInMessage = "I drink goats blood"; })); 

주 대리자 주위에 추가 된 EventHandler

EDIT : EventHandler와 대리자의 함수 서명이 같지 않기 때문에 작동하지 않을 수 있습니다 ... 질문의 맨 아래에 추가 한 해결책이 유일한 방법 일 수 있습니다.

다른 방법으로, 당신은 제네릭 대리자 형식을 만들 수 있습니다 대리인이 거래 특정하지

public delegate void UnitTestingDelegate<T>(T thing); 

그래서. 잘 알려진 오류 메시지의

3

마크 말했다 무엇.

문제는 Do가 Delegate 매개 변수를 사용한다는 것입니다. 컴파일러는 익명 메소드를 Delegate로 변환 할 수 없으며, "Delegate Type"즉, Delegate에서 파생 된 구체적인 유형 만 변환 할 수 있습니다.

Do 함수가 액션 <>, 액션 <,> ... 등을 오버로드하면 작업하지 않아도됩니다.

1

Do() 메서드의 매개 변수가 System.Delegate 형식이고 컴파일러에서 생성 된 대리자 형식 (FakeSave)이 System.Delegate로 암시 적으로 변환되지 않는다는 문제가 대리자 정의에 없습니다.

시도 익명 대표의 앞에 캐스트 추가 :

Expect.Call(delegate { _dao.Save(t); }).Do((Delegate)delegate { t.Message = "I drink goats blood"; }); 
+0

이것은 작동하지 않습니다 대리인 {}은 익명의 함수로 형식이 아닙니다. System.Delegate는 선언 된 모든 대리자 형식의 암시 적 기본 클래스 인 추상 기본 클래스입니다. 위임자라는 단어에는 실제로 3 가지 용도가 있습니다. 대리자 유형 (예 : EvantHandler, Action, Func )을 대리인에게 다운 캐스팅 할 수 있지만 실제로는 위임 유형을 먼저 만들어야합니다! –