Powód jest następujący:
Sposób deklarowania delegata wskazuje bezpośrednio na ToString
metodę statycznej instancji int. Jest schwytany w czasie stworzenia.
Jak Flindeberg wskazuje w komentarzach poniżej, każdy delegat ma cel i metodę, która ma zostać wykonana na miejscu docelowym.
W tym przypadku metodą do wykonania jest oczywiście ToString
metoda. Interesującą częścią jest instancja, na której jest wykonywana metoda: jest to instancja I
w momencie tworzenia, co oznacza, że delegat nie używa I
instancji do użycia, ale przechowuje odwołanie do samej instancji.
Później zmieniasz I
na inną wartość, po prostu przypisując jej nową instancję. Nie zmienia to w magiczny sposób instancji przechwyconej w Twoim delegacie, dlaczego miałoby to robić?
Aby uzyskać oczekiwany wynik, musisz zmienić delegata na następujący:
static Func<string> del = new Func<string>(() => I.ToString());
W ten sposób delegat wskazuje na anonimową metodę, która jest wykonywana ToString
na bieżąco I
w momencie wykonywania delegata.
W tym przypadku metoda do wykonania jest metodą anonimową utworzoną w klasie, w której jest zadeklarowany delegat. Instancja ma wartość null, ponieważ jest metodą statyczną.
Przyjrzyj się kodowi, który kompilator generuje dla drugiej wersji delegata:
private static Func<string> del = new Func<string>(UserQuery.<.cctor>b__0);
private static string cctor>b__0()
{
return UserQuery.I.ToString();
}
Jak widać, jest to normalna metoda, która coś robi . W naszym przypadku zwraca wynik wywołania ToString
bieżącego wystąpienia I
.