2011-01-22 2 views
2
string reference; 
do { 
    reference = GenerateNewReference(); 
} while (currentItems.Exists(i=>i.Reference.Equals(reference)); 

ReSharper가 Access to Modified Closure라고하는 경고 메시지입니다. 나는 그것을 읽고 이해하기 위해 최선을 다했지만, 여전히 내 코드는 나에게 잘 보인다.Do .. While Exists 술어. 수정 된 폐쇄에 대한 액세스?

내 코드에 문제가 있습니까?

답변

2

아니요, List<T>.Exists 메서드가 열심히 실행되기 때문에 문제가 없습니다. 결과적으로, 캡처 된 변수의 값 변경은 즉시 "응답 됨"입니다. do에는 수정 된 클로저가 있지만 반드시 (이 경우처럼) 잘못 될 필요는 없습니다.

반면에 "lambda"(실제로 대리자)를 루프 내부 목록에 추가 한 다음 나중에이 쿼리를 실행하면 Resharper의 실제 수정 된 클로저 문제가 발생합니다 당신에 대해 경고하고 있습니다. 희망이 경고를 제거하는 경우

, 당신은 할 수 :

string reference; 
do { 
    reference = GenerateNewReference(); 
    var refCopy = reference; 
} while (currentItems.Exists(i => i.Reference.Equals(refCopy)); 

약간 오프 주제 : 당신은 수정 된 폐쇄 경고없이 (검색을 작성하는 방법의 멋진을 원하는 경우), 당신은 같은 유틸리티 메소드를 작성할 수

public static IEnumerable<T> Generate(Func<T> func) 
{ 
    if(func == null) 
     throw new ArgumentNullException("func"); 

    while(true) 
     yield return func(); 
} 

그리고로 사용 :

var result = MyExtensions.Generate(GenerateNewReference) 
         .First(reference => !currentItems.Exists(i => i.Reference.Equals(reference))); 
4

reference의 값이 람다의 수명 기간 동안 변경되지 않기 때문에 문제가되지 않습니다. 그러나 resharper는 그것을 모릅니다. resharper가 람다가 더 오랜 시간 생존 할 수 있다는 것을 볼 수있는 한, reference은 값을 변경합니다. IsOne 람다 값에 의해 참조 myInt에 결합, 그리고

int myInt=1; 
Func<int,bool> IsOne = i=>i==myInt; 
myInt=2; 
IsOne(1);//=> false 
IsOne(2);//=> true 

때문에 :이 같은 코드를 작성할 때

규칙

당신을 경고하기위한 것입니다.

관련 문제