Powód jest następujący:
Sposób deklarowania delegata wskazuje bezpośrednio na ToStringmetodę 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 ToStringmetoda. Interesującą częścią jest instancja, na której jest wykonywana metoda: jest to instancja Iw momencie tworzenia, co oznacza, że delegat nie używa Iinstancji do użycia, ale przechowuje odwołanie do samej instancji.
Później zmieniasz Ina 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 ToStringna bieżąco Iw 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 ToStringbieżącego wystąpienia I.