Yamcha
Yamcha

Reputation: 1334

c# delegate not working as it should?

im kinda new to c#, so I came up with this problem. Question: why is func2 called? oh, and one more thing. say I add a function to a delegate. In this function I call another delegate, however I want to make sure that every other function added to the first delegate is called before this function calls this delegate, is there any clean solution ( not really interested in getInvocationList). Thanks guys, you're the best.

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();
    }
}

Upvotes: 10

Views: 3402

Answers (2)

Eric Lippert
Eric Lippert

Reputation: 660040

Reed is of course correct. Here's another way to think about it.

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(); 
    }
}

Should that print 1, 1, or 1, 2? Why?

It should print 1, 1. When you say

test.DoIt();

that does not mean

        Console.WriteLine(test.x);
        test = test.AddOne();
        Console.WriteLine(test.x);

! Rather, that means

Number temporary = test;
Console.WriteLine(temporary.x);
test = test.AddOne();
Console.WriteLine(temporary.x);

Changing the value of test does not change the value of this in DoIt.

You're doing exactly the same thing. Changing the value of test does not change the list of functions that you are invoking; you asked for a particular list of functions to be invoked and that list is going to be invoked. You don't get to change it halfway through, any more than you get to change the meaning of this halfway through a method call.

Upvotes: 7

Reed Copsey
Reed Copsey

Reputation: 564413

Every time you change a delegate (+= or -=), you're effectively creating an entire copy of the invocation list (the methods that will get called).

Because of that, when you call p.test();, you're going to invoke every delegate in the invocation list at that point in time. Changing this inside of one of those handlers will change it for the next call, but won't change the currently executing call.

Upvotes: 21

Related Questions