Are delegates copied during event assignment?
The following code appears to execute the FileRetrieved event more than once. I thought delegates were a reference type. I expected this to happen once. I'm going to guess and say that the link is passed by value, so copied, but I don't like guesswork :-)
public delegate void DirListEvent<T>(T dirItem);
void Main()
{
DirListEvent<string> printFilename = s => {
Console.WriteLine (s);
};
var obj = new DirectoryLister();
obj.FileRetrieved += printFilename;
obj.FileRetrieved += printFilename;
obj.GetDirListing();
}
public class DirectoryLister {
public event DirListEvent<string> FileRetrieved;
public DirectoryLister() {
FileRetrieved += delegate {};
}
public void GetDirListing() {
foreach (var file in Directory.GetFiles(@"C:\"))
{
FileRetrieved(file);
}
}
}
a source to share
Basically, each delegate instance comes with an invocation list , which is essentially a list of all the target event references that you bind to. For instance,
public event DirListEvent<string> FileRetrieved;
the above code creates a type of delegation called FileRetrieved (as you already know). This delegate type now has an invocation list that stores all delegate instances that you register using the + = operator or Delegate.Combine method.
obj.FileRetrieved += printFilename; obj.FileRetrieved += printFilename;
This code basically adds 2 of the same delegate instances to the FileRetrieved call list. Call list allows duplicate instances. Hence, when FileRetrieved is called, it goes through its invocation list and finds that 2 methods have been added (both printFilename) and just delegates the calls to printFilename as it was supposed to.
Try one more line obj.FileRetrieved += printFilename;
and FileRetrieved should call printFilename 3 times.
a source to share