С# делегат не работает так, как должен?
im kinda new для С#, поэтому я придумал эту проблему. Вопрос: почему func2 называется?
Да, и еще одна вещь. Я добавляю функцию к делегату. В этой функции я вызываю другого делегата, однако я хочу удостовериться, что каждая другая функция, добавленная к первому делегату, вызывается до того, как эта функция вызовет этот делегат, есть ли какое-то чистое решение (не очень заинтересованное getInvocationList).
Спасибо, ребята, ты лучший.
class Program
{
delegate void voidEvent();
voidEvent test;
private void func1()
{
Console.Write("func1");
test -= func2;
}
private void func2()
{
Console.WriteLine("func2");
}
static void Main(string[] args)
{
Program p = new Program();
p.test += p.func1;
p.test += p.func2;
p.test();
}
}
Ответы
Ответ 1
Каждый раз, когда вы меняете делегата (+ = или - =), вы фактически создаете целую копию списка вызовов (методы, которые будут вызваны).
Из-за этого, когда вы вызываете p.test();
, вы будете вызывать каждый делегат в списке вызовов в этот момент времени. Изменение этого внутри одного из этих обработчиков изменит его для следующего вызова, но не изменит текущий исполняемый вызов.
Ответ 2
Рид, конечно, правильный. Вот еще один способ подумать об этом.
class Number
{
public static Number test;
private int x;
public Number(int x) { this.x = x; }
public Number AddOne()
{
return new Number(x + 1);
}
public void DoIt()
{
Console.WriteLine(x);
test = test.AddOne();
Console.WriteLine(x);
}
public static void Main()
{
test = new Number(1);
test.DoIt();
}
}
Должна ли печать 1, 1 или 1, 2? Почему?
Он должен печатать 1, 1. Когда вы говорите
test.DoIt();
что не означает
Console.WriteLine(test.x);
test = test.AddOne();
Console.WriteLine(test.x);
! Скорее, это означает
Number temporary = test;
Console.WriteLine(temporary.x);
test = test.AddOne();
Console.WriteLine(temporary.x);
Изменение значения test
не меняет значение this
в DoIt.
Вы делаете то же самое. Изменение значения test
не изменяет список функций, которые вы вызываете; вы попросили указать конкретный список функций, которые будут вызываться, и этот список будет вызван. Вы не можете изменить его на полпути, больше, чем вы можете изменить значение this
на полпути вызова метода.