문제

string [] files = new string[2];
files[0] = "ThinkFarAhead.Example.Settings.Configuration_Local.xml";
files[1] = "ThinkFarAhead.Example.Settings.Configuration_Global.xml";

//Resharper complains this is an "access to modified closure"
for (int i = 0; i < files.Length; i++ )
{
    // Resharper disable AccessToModifiedClosure
    if(Array.Exists(Assembly.GetExecutingAssembly().GetManifestResourceNames(),
    delegate(string name) { return name.Equals(files[i]); }))
         return Assembly.GetExecutingAssembly().GetManifestResourceStream(files[i]);
    // ReSharper restore AccessToModifiedClosure
}

Resharper는 이것이 "수정 된 폐쇄에 대한 액세스"라고 불평하지만 위의 내용은 잘 작동하는 것 같습니다. 누구든지 이것에 빛을 비출 수 있습니까?

(이 주제는 계속되었습니다 여기)

도움이 되었습니까?

해결책

이 경우 실제로 대의원을 실행하고 있기 때문에 괜찮습니다. 이내에 루프.

그러나 대의원을 저장하고 나중에 사용하는 경우, 파일에 액세스하려고 할 때 모든 대표자들이 예외를 제외 할 것임을 알게 될 것입니다. 변하기 쉬운 i 대표단 창조 시점의 가치보다는.

요컨대, 그것은 잠재적인 함정이지만이 경우에는 해를 끼치 지 않습니다.

참조 이 페이지의 하단 결과가 반 직관적 인 더 복잡한 예를 위해서.

다른 팁

나는 이것이 오래된 질문이라는 것을 알고 있지만 최근에 폐쇄를 연구하고 있으며 코드 샘플이 유용 할 수 있다고 생각했습니다. 무대 뒤에서 컴파일러는 기능 호출에 대한 어휘 폐쇄를 나타내는 클래스를 생성합니다. 아마도 다음과 같습니다.

private sealed class Closure
{
    public string[] files;
    public int i;

    public bool YourAnonymousMethod(string name)
    {
        return name.Equals(this.files[this.i]);
    }
}

위에서 언급했듯이, 당신의 기능은 창조 직후에 발행인이 호출되므로 작동합니다. 컴파일러는 다음과 같은 것을 생성합니다.

private string Works()
{
    var closure = new Closure();

    closure.files = new string[3];
    closure.files[0] = "notfoo";
    closure.files[1] = "bar";
    closure.files[2] = "notbaz";

    var arrayToSearch = new string[] { "foo", "bar", "baz" };

    //this works, because the predicates are being executed during the loop
    for (closure.i = 0; closure.i < closure.files.Length; closure.i++)
    {
        if (Array.Exists(arrayToSearch, closure.YourAnonymousMethod))
            return closure.files[closure.i];
    }

    return null;
}

반면에, 당신이 저장하고 나중에 Predicates를 호출한다면, 당신은 predicates에 대한 모든 단일 호출이 실제로 폐쇄 클래스의 동일한 인스턴스에서 동일한 방법을 호출 할 것이므로 동일한 값을 사용한다는 것을 알 수 있습니다. 나.

"파일"은 a입니다 캡처 된 외부 변수 익명의 대의원 함수에 의해 캡처 되었기 때문입니다. 평생은 익명의 대의원 기능에 의해 확장됩니다.

캡처 된 외부 변수 외부 변수가 익명 함수에 의해 참조되면, 외부 변수는 익명 함수에 의해 캡처되었다고합니다. 일반적으로 로컬 변수의 수명은 블록이 관련된 블록 또는 명령문의 실행 (로컬 변수)으로 제한됩니다. 그러나, 캡처 된 외부 변수의 수명은 익명 함수에서 생성 된 대의원 또는 표현식 트리가 쓰레기 수집에 적합해질 때까지 확장됩니다.

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-scification/expressions#outer-variables

로컬 변수 또는 값 매개 변수가 익명 함수에 의해 캡처되면, 로컬 변수 또는 매개 변수는 더 이상 고정 변수 (고정 및 움직일 수있는 변수)로 간주되지 않고 이동 가능한 변수로 간주됩니다. 따라서 캡처 된 외부 변수의 주소를 취하는 안전하지 않은 코드는 먼저 변수를 고정하려면 고정 문을 사용해야합니다. 캡처되지 않은 변수와 달리 캡처 된 로컬 변수는 여러 실행 스레드에 동시에 노출 될 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top