Причина в следующем:
То, как вы объявляете делегата, указывает непосредственно на метод ToString
статического экземпляра int. Он зафиксирован во время создания.
Как указывает Флиндеберг в комментариях ниже, у каждого делегата есть цель и метод, который должен выполняться на цели.
В этом случае, очевидно, что выполняемый метод - это метод 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
.
28.11.2012
static Func<string> del = new Func<string>(I.ToString);
сделает боксI
, а del всегда будет ссылаться на метод ToSting того времениI
? 28.11.2012static Func<string> del = new Func<string>(Program.GetI)
, гдеProgram.GetI
- статическая функция, которая возвращает статическийI
. И результат был 10. Поэтому сейчас, на мой взгляд, связывание делегата с I.ToString приводит к боксу I, а использование анонимного метода также приводит к боксу, но только в том месте, где я вызываю делегат этим анонимным методом. Это правильно? Или мне еще раз прочитать свои книги? :)) 28.11.2012int
сохраняется как цель (что объясняет поведение, поскольку, если он ссылается на хранящийся в стеке неупакованный int, значение изменится). 28.11.2012I
является типом значения. И это утверждение должно быть правильным. 28.11.2012