2011-01-27 9 views
1

(C# 3.0 및 VS 2008).Lambda를 반환하는 메서드에 매개 변수를 전달하는 것에 대한 질문

[Test] 
public void MyPropertyRaisesPropertyChangedWhenChanged(){ 
    var mySUT = CreateSUT(); 

    bool eventRaised = false; 
    string propName = ""; 

    mySUT.PropertyChanged += 
     (s,e)=>{eventRaised = true;propName = e.PropertyName;}; 

    Assert.That(mySUT.MyProperty,Is.False(),"mySUT.MyProperty"); 

    mySUT.MyProperty = true; 

    Assert.That(eventRaised,"eventRaised"); 
    Assert.That(propName, Is.EqualTo("MyProperty"),"propName"); 

    // could check not raised when set same... 
} 

나는이 같은 방법으로 실험 :

public bool MyProperty { 
    get{return _myProperty;} 
    set{ 
     if(_myProperty == value)return; 
     _myProperty = value; 
     RaisePropertyChanged("MyProperty"); 
    } 
} 

가 나는 종종 같은 테스트를 작성 결국 TDD를 수행 : MVVM WPF를하는

은 종종 다음과 같은 속성을 쓸 물건

public class MyTestMethods{ 

    public static PropertyChangedEventHandler MakePropertyChangedHandler(
     bool eventWasRaised, string propertyName){  

     return (s,e)=>{eventWasRaised = true; propertyName = e.PropertyName}; 

    } 
} 

내 테스트를 작성할 수 있도록 :

[Test] 
    public void MyPropertyRaisesPropertyChangedWhenChanged(){ 
     var mySUT = CreateSUT(); 

     bool eventRaised = false; 
     string propName = ""; 

     mySUT.PropertyChanged += 
      MyTestMethods.MakePropertyChangedHandler(eventRaised,propName); 

     // etc... 
} 

그러나 VS2008은 eventRaised가 항상 거짓이라고 말했습니다.

나는 어쩌면 MakePropertyChangedHandler가

public static PropertyChangedEventHandler MakePropertyChangedHandler(
     ref bool eventWasRaised, ref string propertyName){ 

     return // lambda... 

    } 

을 일하는 것이 심판 매개 변수를 사용하여 변경 알았는데으로 VisualStudio는 '익명 메소드 본체 내부에'X '심판 또는 매개 변수에서를 사용할 수 없습니다'나에게 말한다.

MakePropertyChangedHandler와 같은 작업 방법을 쓸 수 있다면 누구나 말해 줄 수 있습니까?

+1

이것이 문제가되는 이유는 http://stackoverflow.com/questions/1365689/cannot-use-ref-or-out-parameter-in-lambda-expressions – Justin

+0

@Justin, 링크를 제공해 주셔서 감사합니다. – Grokodile

답변

2

적절한 수명주기 관리가 보장 될 수 없으므로 람다를 참조 할 수 없습니다. 컴파일러 클로저 (외부 영역 변수를 사용하여, λ)을 만나면

  1. 랩 모두
  2. 스택에 변수를 할당하는 오브젝트의 인스턴스를 대신 생성 익명 객체 로컬 변수를 캡처

는 람다 코드이 객체의 방법 및이 대상에

  • 반환 대리자 및 방법합니다 (자세한 내용은 약간 다를 수 있습니다,하지만 그 원칙입니다). 이 방법은 캡처 된 변수가 대리자가하는 한 존재합니다.

    그러나 스택 위로 높은 함수를 컴파일 할 때 컴파일러는이를 알지 못하므로 스택에 변수를 할당합니다. 더 빠르지 만 변수는 함수가 반환 될 때까지만 존재합니다. 클로저가 그것보다 오래 살 수 있기 때문에 (당신의 경우에는 컴파일러가 알 수 없다), 클로저는 스택 변수를 참조 할 수 없다.

    당신이 할 수있는 것은 참조 의미론을 가진 객체를 생성하고 그것을 클로저에주는 것입니다. 사용자가 만든 그래서 만약 :

    class BoolHolder { 
        public bool value; 
    }; 
    

    패스 BoolHolder를 람다와 람다 당신이 외부의 변화를 볼 수보다

    boolHolder.value = true; 
    

    을한다.

  • +0

    유용한 설명과 해결 방법 제안을 보내 주셔서 감사합니다. – Grokodile

    관련 문제