0

I am playing around with delegates and I came to the situation where I am not sure what is going on.

In my logic, invocation list of "greetings" delegate should return 2, but it just returns 1. As you can see, I am passing the delegate reference to the object I created. I wanted to confirm that delegate can reference private methods from outside and only requirement is that the method is accessible during the assigment of method to the delegate.

 class Program { static void Main(string[] args) { Action greetings = FirstGreeting; Test test = new Test(); test.AddGreeting(greetings); Console.WriteLine(greetings.GetInvocationList().Count()); greetings(); Console.ReadLine(); } static void FirstGreeting() { Console.WriteLine("This is the first greeting."); } } class Test { public void AddGreeting(Action greetings) { greetings += new Action(SecondGreeting); } private void SecondGreeting() { Console.WriteLine("This is the second greeting."); } } 

2 Answers 2

4

As you can see, I am passing the delegate reference to the object I created.

Yes, but you're then using:

greetings += new Action(SecondGreeting); 

This creates a new delegate - it doesn't change the existing delegate. Delegates are immutable, like strings. If you really want the code to work the way you'd expected, you'd have to use:

public void AddGreeting(ref Action greetings) { greetings += new Action(SecondGreeting); } 

and call it as

test.AddGreeting(ref greetings); 

(Or return a reference to the the new delegate, as shown in Peter's answer.)

See my article on delegates and events for more details about what += does.

Sign up to request clarification or add additional context in comments.

Comments

1

I've just tried your code and can see what you mean. If you add a line to your AddGreeting() method which prints out the invocation list at that point, you will see two methods in there. But as Jon Skeet has pointed out delegates are immutable and you have not returned the new (multicast) delegate created.

I suggest you change your method to this:

public Action AddGreeting(Action greetings) { return greetings + new Action(SecondGreeting); } 

as this will now give you the correct set of invocations.

1 Comment

Yup, that's an alternative to passing by reference.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.