Причина в наступному:
Те, як ви оголошуєте делегата, вказує безпосередньо на ToString
метод статичного екземпляра int. Він захоплюється під час створення.
Як зазначає flindeberg у коментарях нижче, кожен делегат має ціль та метод, який слід виконати на цілі.
У цьому випадку метод, який слід виконати, очевидно є ToString
методом. Цікавою частиною є екземпляр, на якому виконується метод: це екземпляр I
на момент створення, тобто делегат не використовує, I
щоб змусити екземпляр використовувати, але він зберігає посилання на сам екземпляр.
Пізніше ви змінюєте I
інше значення, в основному призначаючи йому новий екземпляр. Це магічним чином не змінює екземпляр, захоплений вашим делегатом, навіщо це робити?
Щоб отримати очікуваний результат, вам слід змінити делегата на такий:
static Func<string> del = new Func<string>(() => I.ToString());
Подібно до цього, делегат вказує на анонімний метод, який виконується ToString
на поточному I
на момент виконання делегата.
У цьому випадку виконуваний метод - це анонімний метод, створений у класі, в якому оголошено делегат. Екземпляр є нульовим, оскільки це статичний метод.
Погляньте на код, який компілятор створює для другої версії делегата:
private static Func<string> del = new Func<string>(UserQuery.<.cctor>b__0);
private static string cctor>b__0()
{
return UserQuery.I.ToString();
}
Як бачите, це звичайний метод, який щось робить . У нашому випадку він повертає результат виклику ToString
поточного екземпляра I
.