C# Delegates are immutable – but why does that matter

cdelegatesimmutability

This is a followup question to this other question.

Background

Working from the MSDN Delegates Tutorial (C#), I see the following:

Note that once a delegate is created, the method it is associated with never changes — delegate objects are immutable.

And then, in the code sample, I see this (Spread out a little througout the code):

public delegate void ProcessBookDelegate(Book book);

bookDB.ProcessPaperbackBooks(new ProcessBookDelegate(PrintTitle));
bookDB.ProcessPaperbackBooks(new ProcessBookDelegate(totaller.AddBookToTotal));

The Question

Now obviously, the way the code is written here a new delegate is created for each
process. I am guessing the immutability is relevant if you try to do stuff like

ProcessBookDelegate thisIsATest = new ProcessBookDelegate(PrintTitle);
ProcessBookDelegate thisIsATest = new ProcessBookDelegate(totaller.AddBookToTotal);

which should… still compile when thisIsATest is immutable? So what problem has Microsoft solved by making it immutable? What problems would we run into if C# 6 made delegates mutable?

EDIT

I believe the immutability will prevent this:

ProcessBookDelegate thisIsATest = new ProcessBookDelegate(PrintTitle);

thisIsATest.ChangeTheDelegateInABadFashion();

someFunction(thisIsATest); //This function works as normal
                           //because the delegate is unchanged
                           //due to immutability

but the immutability will NOT prevent this:

ProcessBookDelegate thisIsATest = new ProcessBookDelegate(PrintTitle);

thisIsATest = new ProcessBookDelegate(ChangeTheDelegateInABadFashion());

someFunction(thisIsATest); //This function works weird now because
                           //it expected the unchanged delegate

Am I correct in this understanding?

Best Answer

I think you're mixing up what immutability means.

What Immutability Isn't

Take a look at this example:

string s = "Hello";
s = "World";

Are strings immutable? Yes.
Will this compile? Yes.
Have we in any way changed the string instance? No.

We are not making any changes to "Hello". We are creating a string, assigning it to the variable s, then we are creating a new string, and overwriting the variable s with this new string. Immutability does not play a part here.

What Immutability Is

If we were to try something like this:

s.MutateInSomeWay();

where MutateInSomeWay is a method which changes the string "Hello" (the value of s) itself, that would not be valid due to string immutability.

Any methods of string which change it in any way are not really changing it, they are creating a new string with the changed value and returning it to the caller.

but the immutability will NOT prevent this:

ProcessBookDelegate thisIsATest = new ProcessBookDelegate(PrintTitle);  
thisIsATest = new ProcessBookDelegate(ChangeTheDelegateInABadFashion());
someFunction(thisIsATest); //This function works weird now because
//it expected the unchanged delegate

Am I correct in this understanding?

Yes, immutability will not prevent it because it's perfectly valid, you have not mutated any object. Of course, you are not entirely clear on what is ChangeTheDelegateInABadFashion(), so it's hard to be specific.