그 이유는 다음과 같습니다.
대리자를 선언하는 ToString
방식은 정적 int 인스턴스 의 메서드를 직접 가리 킵니다 . 생성 당시 캡처됩니다.
flindeberg가 아래 주석에서 지적했듯이 각 대리자는 대상에서 실행할 대상과 메서드를 가지고 있습니다.
이 경우 실행될 ToString
메서드 는 분명히 메서드입니다. 흥미로운 부분은 메서드가 실행되는 인스턴스입니다 I
. 생성 당시의 인스턴스입니다 . 즉, 대리자가 I
사용할 인스턴스를 가져 오는 데 사용하지 않지만 인스턴스 자체에 대한 참조를 저장합니다.
나중에 I
다른 값으로 변경 하여 기본적으로 새 인스턴스를 할당합니다. 이것은 델리게이트에서 캡처 된 인스턴스를 마술처럼 변경하지 않습니다. 왜 그래야합니까?
예상 한 결과를 얻으려면 대리자를 다음과 같이 변경해야합니다.
static Func<string> del = new Func<string>(() => I.ToString());
이와 같이 대리자는 대리자를 실행할 ToString
때 현재 I
에서 실행되는 익명 메서드를 가리 킵니다 .
이 경우 실행할 메서드는 델리게이트가 선언 된 클래스에서 생성 된 익명 메서드입니다. 인스턴스는 정적 메서드이므로 null입니다.
컴파일러가 대리자의 두 번째 버전에 대해 생성하는 코드를 살펴보십시오.
private static Func<string> del = new Func<string>(UserQuery.<.cctor>b__0);
private static string cctor>b__0()
{
return UserQuery.I.ToString();
}
보시다시피, 이것은 무언가를 하는 일반적인 방법입니다 . 우리의 경우에는 ToString
의 현재 인스턴스를 호출 한 결과를 반환합니다 I
.